Compare commits

..
Author SHA1 Message Date
James Turner 506b9130a8 Adjust where we set the deployment SDK on Mac.
Contrary to the CMake docs, settings this value before project()
seems not to work, whereas setting it after works exactly as
desired.
2015-02-18 10:06:03 +00:00
James Turner 5d1b70a7f2 Force SDK version / C++ library on Mac. 2015-02-13 14:47:45 +00:00
Peter Sadrozinski eff3df57d9 memory reduced tile loading.
- do not save the TileGeometryBin and matcach in the randomObjectCallback
- recreate matcache, and get TileGeometry from scenegraph
- split obj.cxx into three distinct files - loadBTG, load surface geometry, and load tile details
- includes fix for sceneries that have missing materials
2015-02-11 09:04:53 +01:00
Rebecca N. Palmer 2931f3380f Fix UpdateOnceCallback crash (bug 1554/1556/1568)
(cherry picked from commit dc1816bb08)
2015-01-19 15:51:36 +00:00
114 changed files with 1452 additions and 3552 deletions
+15 -75
View File
@@ -1,29 +1,14 @@
cmake_minimum_required (VERSION 2.8.11) cmake_minimum_required (VERSION 2.6.4)
if(COMMAND cmake_policy)
if(POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
endif()
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
endif()
include (CheckFunctionExists) include (CheckFunctionExists)
include (CheckIncludeFile) include (CheckIncludeFile)
include (CheckLibraryExists)
include (CheckCXXSourceCompiles) include (CheckCXXSourceCompiles)
include (CheckCXXCompilerFlag) include (CheckCXXCompilerFlag)
include (GenerateExportHeader)
project(SimGear)
# using 10.7 because boost requires libc++ and 10.6 doesn't include it # using 10.7 because boost requires libc++ and 10.6 doesn't include it
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7) set(CMAKE_OSX_DEPLOYMENT_TARGET 10.7)
# only relevant for building shared libs but let's set it regardless
set(CMAKE_OSX_RPATH 1)
project(SimGear)
# read 'version' file into a variable (stripping any newlines or spaces) # read 'version' file into a variable (stripping any newlines or spaces)
file(READ version versionFile) file(READ version versionFile)
string(STRIP ${versionFile} SIMGEAR_VERSION) string(STRIP ${versionFile} SIMGEAR_VERSION)
@@ -80,7 +65,12 @@ endif(NOT CMAKE_BUILD_TYPE)
# Determine name of library installation directory, i.e. "lib" vs "lib64", which # Determine name of library installation directory, i.e. "lib" vs "lib64", which
# differs between all Debian-based vs all other Linux distros. # 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 # See cmake bug #11964, http://cmake.org/gitweb?p=cmake.git;a=commit;h=126c993d
include(GNUInstallDirs) # 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}") message(STATUS "Library installation directory: ${CMAKE_INSTALL_LIBDIR}")
##################################################################################### #####################################################################################
@@ -117,7 +107,6 @@ 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) option(ENABLE_TESTS "Set to OFF to disable building SimGear's test applications" ON)
option(ENABLE_SOUND "Set to OFF to disable building SimGear's sound support" ON) option(ENABLE_SOUND "Set to OFF to disable building SimGear's sound support" ON)
option(ENABLE_PKGUTIL "Set to ON to build the sg_pkgutil application (default)" ON) option(ENABLE_PKGUTIL "Set to ON to build the sg_pkgutil application (default)" ON)
option(ENABLE_CURL "Set to ON to use libCurl as the HTTP client backend" OFF)
if (MSVC) if (MSVC)
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH) GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
@@ -175,23 +164,13 @@ endif (MSVC AND MSVC_3RDPARTY_ROOT)
if(APPLE) if(APPLE)
find_library(COCOA_LIBRARY Cocoa) find_library(COCOA_LIBRARY Cocoa)
# this should be handled by setting CMAKE_OSX_DEPLOYMENT_TARGET
# but it's not working reliably, so forcing it for now
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mmacosx-version-min=10.7")
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mmacosx-version-min=10.7")
endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux" OR
${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
find_package(Threads REQUIRED)
endif() endif()
# Somehow this only works if included before searching for Boost... # Somehow this only works if included before searching for Boost...
include(BoostTestTargets) include(BoostTestTargets)
find_package(Boost REQUIRED) find_package(Boost REQUIRED)
set (BOOST_CXX_FLAGS "-DBOOST_BIMAP_DISABLE_SERIALIZATION") set (BOOST_CXX_FLAGS "-DBOOST_MULTI_INDEX_DISABLE_SERIALIZATION -DBOOST_BIMAP_DISABLE_SERIALIZATION")
if(SIMGEAR_HEADLESS) if(SIMGEAR_HEADLESS)
message(STATUS "SimGear mode: HEADLESS") message(STATUS "SimGear mode: HEADLESS")
@@ -209,11 +188,7 @@ else()
endif(SIMGEAR_HEADLESS) endif(SIMGEAR_HEADLESS)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
find_package(Threads REQUIRED)
if (ENABLE_CURL)
find_package(CURL REQUIRED)
message(STATUS "Curl HTTP client: ENABLED")
endif()
if (SYSTEM_EXPAT) if (SYSTEM_EXPAT)
message(STATUS "Requested to use system Expat library, forcing SIMGEAR_SHARED to true") message(STATUS "Requested to use system Expat library, forcing SIMGEAR_SHARED to true")
@@ -325,8 +300,7 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_COMPILER_IS_GNUCXX) endif(CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Boost redeclares class members set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual")
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual -Wno-redeclared-class-member")
set(WARNING_FLAGS_C "-Wall") set(WARNING_FLAGS_C "-Wall")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11") set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
@@ -380,7 +354,6 @@ include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS} ${Boost_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR} ${OPENAL_INCLUDE_DIR}
${CURL_INCLUDE_DIRS}
) )
add_definitions(-DHAVE_CONFIG_H) add_definitions(-DHAVE_CONFIG_H)
@@ -409,8 +382,7 @@ set(TEST_LIBS_INTERNAL_CORE
${WINSOCK_LIBRARY} ${WINSOCK_LIBRARY}
${RT_LIBRARY} ${RT_LIBRARY}
${DL_LIBRARY} ${DL_LIBRARY}
${COCOA_LIBRARY} ${COCOA_LIBRARY})
${CURL_LIBRARIES})
set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE}) set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE})
if(NOT SIMGEAR_HEADLESS) if(NOT SIMGEAR_HEADLESS)
@@ -424,40 +396,6 @@ include_directories(3rdparty/utf8/source)
add_subdirectory(3rdparty) add_subdirectory(3rdparty)
add_subdirectory(simgear) add_subdirectory(simgear)
#-----------------------------------------------------------------------------
### Export stuff, see https://cmake.org/cmake/help/v3.2/manual/cmake-packages.7.html#creating-packages
#-----------------------------------------------------------------------------
generate_export_header(SimGearCore)
if(NOT SIMGEAR_HEADLESS)
generate_export_header(SimGearScene)
endif()
include(CMakePackageConfigHelpers)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/SimGear/SimGearConfigVersion.cmake"
VERSION ${SIMGEAR_VERSION}
COMPATIBILITY AnyNewerVersion
)
configure_file(SimGearConfig.cmake.in
"${CMAKE_CURRENT_BINARY_DIR}/SimGear/SimGearConfig.cmake"
@ONLY
)
set(ConfigPackageLocation lib/cmake/SimGear)
install(EXPORT SimGearTargets
DESTINATION ${ConfigPackageLocation}
)
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/SimGear/SimGearConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/SimGear/SimGearConfigVersion.cmake"
DESTINATION ${ConfigPackageLocation}
COMPONENT Devel
)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
### uninstall target ### uninstall target
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
@@ -467,3 +405,5 @@ CONFIGURE_FILE(
IMMEDIATE @ONLY) IMMEDIATE @ONLY)
ADD_CUSTOM_TARGET(uninstall ADD_CUSTOM_TARGET(uninstall
"${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
+182
View File
@@ -0,0 +1,182 @@
# - 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()
-16
View File
@@ -1,16 +0,0 @@
include(CMakeFindDependencyMacro)
find_dependency(ZLIB)
find_dependency(Threads)
# OSG
set(SIMGEAR_HEADLESS @SIMGEAR_HEADLESS@)
set(SIMGEAR_SOUND @ENABLE_SOUND@)
# OpenAL isn't a public dependency, so maybe not needed
#if (SIMGEAR_SOUND)
# find_dependency(OpenAL)
#endif()
include("${CMAKE_CURRENT_LIST_DIR}/SimGearTargets.cmake")
+7 -16
View File
@@ -54,10 +54,8 @@ if(SIMGEAR_SHARED)
set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX) set_property(TARGET SimGearCore PROPERTY LINKER_LANGUAGE CXX)
set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION}) set_property(TARGET SimGearCore PROPERTY VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION}) set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
install(TARGETS SimGearCore install(TARGETS SimGearCore EXPORT SimGearCoreConfig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
EXPORT SimGearTargets install(EXPORT SimGearCoreConfig DESTINATION share/SimGearCore)
LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS) if(NOT SIMGEAR_HEADLESS)
add_library(SimGearScene SHARED ${sceneSources}) add_library(SimGearScene SHARED ${sceneSources})
@@ -66,10 +64,8 @@ if(SIMGEAR_SHARED)
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION}) set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
# EXPORT SimGearSceneConfig # EXPORT SimGearSceneConfig
install(TARGETS SimGearScene install(TARGETS SimGearScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )
EXPORT SimGearTargets # install(EXPORT SimGearSceneConfig DESTINATION share/SimGearScene)
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR} )
endif() endif()
else() else()
@@ -94,9 +90,7 @@ else()
endforeach() endforeach()
add_library(SimGearCore STATIC ${coreSources} ${localExpatSources}) add_library(SimGearCore STATIC ${coreSources} ${localExpatSources})
install(TARGETS SimGearCore install(TARGETS SimGearCore ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS) if(NOT SIMGEAR_HEADLESS)
get_property(FG_GROUPS_SCENE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_C) get_property(FG_GROUPS_SCENE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_C)
@@ -118,9 +112,7 @@ else()
endforeach() endforeach()
add_library(SimGearScene STATIC ${sceneSources}) add_library(SimGearScene STATIC ${sceneSources})
install(TARGETS SimGearScene install(TARGETS SimGearScene ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(NOT SIMGEAR_HEADLESS) endif(NOT SIMGEAR_HEADLESS)
endif(SIMGEAR_SHARED) endif(SIMGEAR_SHARED)
@@ -130,8 +122,7 @@ target_link_libraries(SimGearCore
${DL_LIBRARY} ${DL_LIBRARY}
${EXPAT_LIBRARIES} ${EXPAT_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT} ${CMAKE_THREAD_LIBS_INIT}
${COCOA_LIBRARY} ${COCOA_LIBRARY})
${CURL_LIBRARIES})
if(NOT SIMGEAR_HEADLESS) if(NOT SIMGEAR_HEADLESS)
target_link_libraries(SimGearScene target_link_libraries(SimGearScene
+1 -1
View File
@@ -43,7 +43,7 @@ public:
void removeChild(BVHNode* child); void removeChild(BVHNode* child);
unsigned getNumChildren() const unsigned getNumChildren() const
{ return static_cast<unsigned>(_children.size()); } { return _children.size(); }
const BVHNode* getChild(unsigned i) const const BVHNode* getChild(unsigned i) const
{ if (_children.size() <= i) return 0; return _children[i]; } { if (_children.size() <= i) return 0; return _children[i]; }
BVHNode* getChild(unsigned i) BVHNode* getChild(unsigned i)
+2 -2
View File
@@ -31,13 +31,13 @@ public:
virtual ~BVHStaticData() {} virtual ~BVHStaticData() {}
unsigned addVertex(const SGVec3f& vertex) unsigned addVertex(const SGVec3f& vertex)
{ _vertices.push_back(vertex); return static_cast<unsigned>(_vertices.size() - 1); } { _vertices.push_back(vertex); return _vertices.size() - 1; }
const SGVec3f& getVertex(unsigned i) const const SGVec3f& getVertex(unsigned i) const
{ return _vertices[i]; } { return _vertices[i]; }
unsigned addMaterial(const BVHMaterial* material) unsigned addMaterial(const BVHMaterial* material)
{ _materials.push_back(material); return static_cast<unsigned>(_materials.size() - 1); } { _materials.push_back(material); return _materials.size() - 1; }
const BVHMaterial* getMaterial(unsigned i) const const BVHMaterial* getMaterial(unsigned i) const
{ if (_materials.size() <= i) return 0; return _materials[i]; } { if (_materials.size() <= i) return 0; return _materials[i]; }
+23 -12
View File
@@ -207,6 +207,19 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
Element::~Element() Element::~Element()
{ {
if( !_transform.valid() )
return;
for(unsigned int i = 0; i < _transform->getNumChildren(); ++i)
{
OSGUserData* ud =
static_cast<OSGUserData*>(_transform->getChild(i)->getUserData());
if( ud )
// Ensure parent is cleared to prevent accessing released memory if an
// element somehow survives longer than his parent.
ud->element->_parent = 0;
}
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -233,7 +246,7 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
ElementPtr Element::getParent() const ElementPtr Element::getParent() const
{ {
return _parent.lock(); return _parent;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -311,9 +324,8 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
bool Element::ascend(EventVisitor& visitor) bool Element::ascend(EventVisitor& visitor)
{ {
ElementPtr parent = getParent(); if( _parent )
if( parent ) return _parent->accept(visitor);
return parent->accept(visitor);
return true; return true;
} }
@@ -362,9 +374,9 @@ namespace canvas
EventPropagationPath path; EventPropagationPath path;
path.push_back( EventTarget(this) ); path.push_back( EventTarget(this) );
for( ElementPtr parent = getParent(); for( Element* parent = _parent;
parent.valid(); parent != NULL;
parent = parent->getParent() ) parent = parent->_parent )
path.push_front( EventTarget(parent) ); path.push_front( EventTarget(parent) );
CanvasPtr canvas = _canvas.lock(); CanvasPtr canvas = _canvas.lock();
@@ -760,7 +772,7 @@ namespace canvas
Element::Element( const CanvasWeakPtr& canvas, Element::Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): Element* parent ):
PropertyBasedElement(node), PropertyBasedElement(node),
_canvas( canvas ), _canvas( canvas ),
_parent( parent ), _parent( parent ),
@@ -859,12 +871,11 @@ namespace canvas
Element::getParentStyle(const SGPropertyNode* child) const Element::getParentStyle(const SGPropertyNode* child) const
{ {
// Try to get value from parent... // Try to get value from parent...
ElementPtr parent = getParent(); if( _parent )
if( parent )
{ {
Style::const_iterator style = Style::const_iterator style =
parent->_style.find(child->getNameString()); _parent->_style.find(child->getNameString());
if( style != parent->_style.end() ) if( style != _parent->_style.end() )
return style->second; return style->second;
} }
+2 -2
View File
@@ -233,7 +233,7 @@ namespace canvas
class RelativeScissor; class RelativeScissor;
CanvasWeakPtr _canvas; CanvasWeakPtr _canvas;
ElementWeakPtr _parent; Element *_parent;
mutable uint32_t _attributes_dirty; mutable uint32_t _attributes_dirty;
@@ -256,7 +256,7 @@ namespace canvas
Element( const CanvasWeakPtr& canvas, Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ); Element* parent );
/** /**
* Returns false on first call and true on any successive call. Use to * Returns false on first call and true on any successive call. Use to
+1 -1
View File
@@ -70,7 +70,7 @@ namespace canvas
Group::Group( const CanvasWeakPtr& canvas, Group::Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): Element* parent ):
Element(canvas, node, parent_style, parent) Element(canvas, node, parent_style, parent)
{ {
staticInit(); staticInit();
+1 -1
View File
@@ -45,7 +45,7 @@ namespace canvas
Group( const CanvasWeakPtr& canvas, Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style = Style(), const Style& parent_style = Style(),
ElementWeakPtr parent = 0 ); Element* parent = 0 );
virtual ~Group(); virtual ~Group();
ElementPtr createChild( const std::string& type, ElementPtr createChild( const std::string& type,
+1 -1
View File
@@ -112,7 +112,7 @@ namespace canvas
Image::Image( const CanvasWeakPtr& canvas, Image::Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): Element* parent ):
Element(canvas, node, parent_style, parent), Element(canvas, node, parent_style, parent),
_texture(new osg::Texture2D), _texture(new osg::Texture2D),
_node_src_rect( node->getNode("source", 0, true) ), _node_src_rect( node->getNode("source", 0, true) ),
+1 -1
View File
@@ -50,7 +50,7 @@ namespace canvas
Image( const CanvasWeakPtr& canvas, Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style = Style(), const Style& parent_style = Style(),
ElementWeakPtr parent = 0 ); Element* parent = 0 );
virtual ~Image(); virtual ~Image();
virtual void update(double dt); virtual void update(double dt);
+31 -69
View File
@@ -44,7 +44,6 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
const std::string GEO = "-geo"; const std::string GEO = "-geo";
const std::string HDG = "hdg";
const std::string Map::TYPE_NAME = "map"; const std::string Map::TYPE_NAME = "map";
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
@@ -62,7 +61,7 @@ namespace canvas
Map::Map( const CanvasWeakPtr& canvas, Map::Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): Element* parent ):
Group(canvas, node, parent_style, parent), Group(canvas, node, parent_style, parent),
// TODO make projection configurable // TODO make projection configurable
_projection(new SansonFlamsteedProjection), _projection(new SansonFlamsteedProjection),
@@ -113,89 +112,39 @@ namespace canvas
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::childAdded(SGPropertyNode* parent, SGPropertyNode* child) void Map::childAdded(SGPropertyNode* parent, SGPropertyNode* child)
{ {
if( boost::ends_with(child->getNameString(), GEO) ) if( !boost::ends_with(child->getNameString(), GEO) )
_geo_nodes[child].reset(new GeoNodePair());
else if( parent != _node && child->getNameString() == HDG )
_hdg_nodes.insert(child);
else
return Element::childAdded(parent, child); return Element::childAdded(parent, child);
_geo_nodes[child].reset(new GeoNodePair());
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::childRemoved(SGPropertyNode* parent, SGPropertyNode* child) void Map::childRemoved(SGPropertyNode* parent, SGPropertyNode* child)
{ {
if( boost::ends_with(child->getNameString(), GEO) ) if( !boost::ends_with(child->getNameString(), GEO) )
return Element::childRemoved(parent, child);
// TODO remove from other node // TODO remove from other node
_geo_nodes.erase(child); _geo_nodes.erase(child);
else if( parent != _node && child->getName() == HDG )
{
_hdg_nodes.erase(child);
// Remove rotation matrix (tf[0]) and return to element always being
// oriented upwards (or any orientation inside other matrices).
child->getParent()->removeChild("tf", 0);
}
else
return Element::childRemoved(parent, child);
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::valueChanged(SGPropertyNode* child) void Map::valueChanged(SGPropertyNode * child)
{
if( child->getParent() != _node )
{ {
const std::string& name = child->getNameString(); const std::string& name = child->getNameString();
if( boost::ends_with(name, GEO) ) if( !boost::ends_with(name, GEO) )
return geoNodeChanged(child);
else if( name == HDG )
return hdgNodeChanged(child);
}
return Group::valueChanged(child); return Group::valueChanged(child);
}
//----------------------------------------------------------------------------
void Map::childChanged(SGPropertyNode* child)
{
if( child->getParent() != _node )
return Group::childChanged(child);
if( child->getNameString() == "ref-lat"
|| child->getNameString() == "ref-lon" )
_projection->setWorldPosition( _node->getDoubleValue("ref-lat"),
_node->getDoubleValue("ref-lon") );
else if( child->getNameString() == HDG )
{
_projection->setOrientation(child->getFloatValue());
for( NodeSet::iterator it = _hdg_nodes.begin();
it != _hdg_nodes.end();
++it )
hdgNodeChanged(*it);
}
else if( child->getNameString() == "range" )
_projection->setRange(child->getDoubleValue());
else if( child->getNameString() == "screen-range" )
_projection->setScreenRange(child->getDoubleValue());
else
return Group::childChanged(child);
_projection_dirty = true;
}
//----------------------------------------------------------------------------
void Map::geoNodeChanged(SGPropertyNode* child)
{
GeoNodes::iterator it_geo_node = _geo_nodes.find(child); GeoNodes::iterator it_geo_node = _geo_nodes.find(child);
if( it_geo_node == _geo_nodes.end() ) if( it_geo_node == _geo_nodes.end() )
LOG_GEO_RET("GeoNode not found!") LOG_GEO_RET("geo node not found!")
GeoNodePair* geo_node = it_geo_node->second.get(); GeoNodePair* geo_node = it_geo_node->second.get();
geo_node->setDirty(); geo_node->setDirty();
if( !(geo_node->getStatus() & GeoNodePair::INCOMPLETE) ) if( geo_node->getStatus() & GeoNodePair::INCOMPLETE )
return; {
// Detect lat, lon tuples... // Detect lat, lon tuples...
GeoCoord coord = parseGeoCoord(child->getStringValue()); GeoCoord coord = parseGeoCoord(child->getStringValue());
int index_other = -1; int index_other = -1;
@@ -214,7 +163,6 @@ namespace canvas
LOG_GEO_RET("Invalid geo coord") LOG_GEO_RET("Invalid geo coord")
} }
const std::string& name = child->getNameString();
SGPropertyNode *other = child->getParent()->getChild(name, index_other); SGPropertyNode *other = child->getParent()->getChild(name, index_other);
if( !other ) if( !other )
return; return;
@@ -241,14 +189,28 @@ namespace canvas
// Set name for resulting screen coordinate nodes // Set name for resulting screen coordinate nodes
geo_node->setTargetName( name.substr(0, name.length() - GEO.length()) ); geo_node->setTargetName( name.substr(0, name.length() - GEO.length()) );
} }
}
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void Map::hdgNodeChanged(SGPropertyNode* child) void Map::childChanged(SGPropertyNode * child)
{ {
child->getParent()->setFloatValue( if( child->getParent() != _node )
"tf[0]/rot", return Group::childChanged(child);
SGMiscf::deg2rad(child->getFloatValue() - _projection->orientation())
); if( child->getNameString() == "ref-lat"
|| child->getNameString() == "ref-lon" )
_projection->setWorldPosition( _node->getDoubleValue("ref-lat"),
_node->getDoubleValue("ref-lon") );
else if( child->getNameString() == "hdg" )
_projection->setOrientation(child->getFloatValue());
else if( child->getNameString() == "range" )
_projection->setRange(child->getDoubleValue());
else if( child->getNameString() == "screen-range" )
_projection->setScreenRange(child->getDoubleValue());
else
return Group::childChanged(child);
_projection_dirty = true;
} }
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
+2 -10
View File
@@ -24,7 +24,6 @@
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp> #include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
namespace simgear namespace simgear
{ {
@@ -42,7 +41,7 @@ namespace canvas
Map( const CanvasWeakPtr& canvas, Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent = 0 ); Element* parent = 0 );
virtual ~Map(); virtual ~Map();
virtual void update(double dt); virtual void update(double dt);
@@ -60,18 +59,14 @@ namespace canvas
typedef boost::unordered_map< SGPropertyNode*, typedef boost::unordered_map< SGPropertyNode*,
boost::shared_ptr<GeoNodePair> boost::shared_ptr<GeoNodePair>
> GeoNodes; > GeoNodes;
typedef boost::unordered_set<SGPropertyNode*> NodeSet;
GeoNodes _geo_nodes; GeoNodes _geo_nodes;
NodeSet _hdg_nodes;
boost::shared_ptr<HorizontalProjection> _projection; boost::shared_ptr<HorizontalProjection> _projection;
bool _projection_dirty; bool _projection_dirty;
struct GeoCoord struct GeoCoord
{ {
GeoCoord(): GeoCoord():
type(INVALID), type(INVALID)
value(0)
{} {}
enum enum
{ {
@@ -82,9 +77,6 @@ namespace canvas
double value; double value;
}; };
void geoNodeChanged(SGPropertyNode * child);
void hdgNodeChanged(SGPropertyNode * child);
GeoCoord parseGeoCoord(const std::string& val) const; GeoCoord parseGeoCoord(const std::string& val) const;
}; };
+1 -1
View File
@@ -531,7 +531,7 @@ namespace canvas
Path::Path( const CanvasWeakPtr& canvas, Path::Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): Element* parent ):
Element(canvas, node, parent_style, parent), Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) ) _path( new PathDrawable(this) )
{ {
+1 -1
View File
@@ -36,7 +36,7 @@ namespace canvas
Path( const CanvasWeakPtr& canvas, Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent = 0 ); Element* parent = 0 );
virtual ~Path(); virtual ~Path();
virtual void update(double dt); virtual void update(double dt);
+3 -18
View File
@@ -159,12 +159,8 @@ namespace canvas
if( empty() ) if( empty() )
return pos; return pos;
#if OSG_VERSION_LESS_THAN(3,3,5)
GlyphQuads::Coords2 const& coords = _quads->_coords; GlyphQuads::Coords2 const& coords = _quads->_coords;
#else
GlyphQuads::Coords2 refCoords = _quads->_coords;
GlyphQuads::Coords2::element_type &coords = *refCoords.get();
#endif
size_t global_i = _begin + i; size_t global_i = _begin + i;
if( global_i == _begin ) if( global_i == _begin )
@@ -198,12 +194,7 @@ namespace canvas
return cursorPos(0); return cursorPos(0);
GlyphQuads::Glyphs const& glyphs = _quads->_glyphs; GlyphQuads::Glyphs const& glyphs = _quads->_glyphs;
#if OSG_VERSION_LESS_THAN(3,3,5)
GlyphQuads::Coords2 const& coords = _quads->_coords; GlyphQuads::Coords2 const& coords = _quads->_coords;
#else
GlyphQuads::Coords2 refCoords = _quads->_coords;
GlyphQuads::Coords2::element_type &coords = *refCoords.get();
#endif
float const HIT_FRACTION = 0.6; float const HIT_FRACTION = 0.6;
float const character_width = _text->getCharacterHeight() float const character_width = _text->getCharacterHeight()
@@ -636,13 +627,7 @@ namespace canvas
const GlyphQuads& quads = _textureGlyphQuadMap.begin()->second; const GlyphQuads& quads = _textureGlyphQuadMap.begin()->second;
const GlyphQuads::Glyphs& glyphs = quads._glyphs; const GlyphQuads::Glyphs& glyphs = quads._glyphs;
#if OSG_VERSION_LESS_THAN(3,3,5) const GlyphQuads::Coords2& coords = quads._coords;
GlyphQuads::Coords2 const& coords = quads._coords;
#else
GlyphQuads::Coords2 refCoords = quads._coords;
GlyphQuads::Coords2::element_type &coords = *refCoords.get();
#endif
const GlyphQuads::LineNumbers& line_numbers = quads._lineNumbers; const GlyphQuads::LineNumbers& line_numbers = quads._lineNumbers;
float wr = _characterHeight / getCharacterAspectRatio(); float wr = _characterHeight / getCharacterAspectRatio();
@@ -740,7 +725,7 @@ namespace canvas
Text::Text( const CanvasWeakPtr& canvas, Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent ): Element* parent ):
Element(canvas, node, parent_style, parent), Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) ) _text( new Text::TextOSG(this) )
{ {
+1 -1
View File
@@ -40,7 +40,7 @@ namespace canvas
Text( const CanvasWeakPtr& canvas, Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node, const SGPropertyNode_ptr& node,
const Style& parent_style, const Style& parent_style,
ElementWeakPtr parent = 0 ); Element* parent = 0 );
~Text(); ~Text();
void setText(const char* text); void setText(const char* text);
+11 -28
View File
@@ -34,10 +34,7 @@ namespace canvas
public: public:
struct ScreenPosition struct ScreenPosition
{ {
ScreenPosition(): ScreenPosition() {}
x(0),
y(0)
{}
ScreenPosition(double x, double y): ScreenPosition(double x, double y):
x(x), x(x),
@@ -70,11 +67,8 @@ namespace canvas
public: public:
HorizontalProjection(): HorizontalProjection():
_ref_lat(0), _cos_rot(1),
_ref_lon(0), _sin_rot(0),
_angle(0),
_cos_angle(1),
_sin_angle(0),
_range(5) _range(5)
{ {
setScreenRange(200); setScreenRange(200);
@@ -94,19 +88,9 @@ namespace canvas
*/ */
void setOrientation(float hdg) void setOrientation(float hdg)
{ {
_angle = hdg;
hdg = SGMiscf::deg2rad(hdg); hdg = SGMiscf::deg2rad(hdg);
_sin_angle = sin(hdg); _sin_rot = sin(hdg);
_cos_angle = cos(hdg); _cos_rot = cos(hdg);
}
/**
* Get orientation/heading of the projection (in degree)
*/
float orientation() const
{
return _angle;
} }
void setRange(double range) void setRange(double range)
@@ -130,8 +114,8 @@ namespace canvas
pos.y *= scale; pos.y *= scale;
return ScreenPosition return ScreenPosition
( (
_cos_angle * pos.x - _sin_angle * pos.y, _cos_rot * pos.x - _sin_rot * pos.y,
-_sin_angle * pos.x - _cos_angle * pos.y -_sin_rot * pos.x - _cos_rot * pos.y
); );
} }
@@ -145,11 +129,10 @@ namespace canvas
*/ */
virtual ScreenPosition project(double lat, double lon) const = 0; virtual ScreenPosition project(double lat, double lon) const = 0;
double _ref_lat, ///<! Reference latitude (radian) double _ref_lat,
_ref_lon, ///<! Reference latitude (radian) _ref_lon,
_angle, ///<! Map rotation angle (degree) _cos_rot,
_cos_angle, _sin_rot,
_sin_angle,
_range; _range;
}; };
-6
View File
@@ -190,12 +190,6 @@ inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
# define DEPRECATED # define DEPRECATED
#endif #endif
#if defined(__clang__)
# define SG_NO_RETURN [[noreturn]]
#else
# define SG_NO_RETURN
#endif
// //
// No user modifiable definitions beyond here. // No user modifiable definitions beyond here.
// //
+1 -2
View File
@@ -32,8 +32,7 @@ typedef enum {
SG_SOUND = 0x00200000, SG_SOUND = 0x00200000,
SG_NAVAID = 0x00400000, SG_NAVAID = 0x00400000,
SG_GUI = 0x00800000, SG_GUI = 0x00800000,
SG_TERRASYNC = 0x01000000, SG_UNDEFD = 0x01000000, // For range checking
SG_UNDEFD = 0x02000000, // For range checking
SG_ALL = 0xFFFFFFFF SG_ALL = 0xFFFFFFFF
} sgDebugClass; } sgDebugClass;
-1
View File
@@ -71,7 +71,6 @@ const char* debugClassToString(sgDebugClass c)
case SG_SOUND: return "sound"; case SG_SOUND: return "sound";
case SG_NAVAID: return "navaid"; case SG_NAVAID: return "navaid";
case SG_GUI: return "gui"; case SG_GUI: return "gui";
case SG_TERRASYNC: return "terrasync";
default: return "unknown"; default: return "unknown";
} }
} }
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$ * $Id$
**************************************************************************/ **************************************************************************/
#include <cmath> #include <math.h>
#include "jupiter.hxx" #include "jupiter.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$ * $Id$
**************************************************************************/ **************************************************************************/
#include <cmath> #include <math.h>
#include "mars.hxx" #include "mars.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$ * $Id$
**************************************************************************/ **************************************************************************/
#include <cmath> #include <math.h>
#include "mercury.hxx" #include "mercury.hxx"
+1 -1
View File
@@ -25,7 +25,7 @@
#ifdef __BORLANDC__ #ifdef __BORLANDC__
# define exception c_exception # define exception c_exception
#endif #endif
#include <cmath> #include <math.h>
#include "neptune.hxx" #include "neptune.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$ * $Id$
**************************************************************************/ **************************************************************************/
#include <cmath> #include <math.h>
#include "saturn.hxx" #include "saturn.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$ * $Id$
**************************************************************************/ **************************************************************************/
#include <cmath> #include <math.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
+1 -1
View File
@@ -41,7 +41,7 @@ public:
bool load( const SGPath& path ); bool load( const SGPath& path );
// stars // stars
inline int getNumStars() const { return static_cast<int>(_stars.size()); } inline int getNumStars() const { return _stars.size(); }
inline SGVec3d *getStars() { return &(_stars[0]); } inline SGVec3d *getStars() { return &(_stars[0]); }
private: private:
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$ * $Id$
**************************************************************************/ **************************************************************************/
#include <cmath> #include <math.h>
#include "uranus.hxx" #include "uranus.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$ * $Id$
**************************************************************************/ **************************************************************************/
#include <cmath> #include <math.h>
#include "venus.hxx" #include "venus.hxx"
+2 -5
View File
@@ -18,6 +18,7 @@ set(HEADERS
HTTPFileRequest.hxx HTTPFileRequest.hxx
HTTPMemoryRequest.hxx HTTPMemoryRequest.hxx
HTTPRequest.hxx HTTPRequest.hxx
HTTPContentDecode.hxx
DAVMultiStatus.hxx DAVMultiStatus.hxx
SVNRepository.hxx SVNRepository.hxx
SVNDirectory.hxx SVNDirectory.hxx
@@ -40,17 +41,13 @@ set(SOURCES
HTTPFileRequest.cxx HTTPFileRequest.cxx
HTTPMemoryRequest.cxx HTTPMemoryRequest.cxx
HTTPRequest.cxx HTTPRequest.cxx
HTTPContentDecode.cxx
DAVMultiStatus.cxx DAVMultiStatus.cxx
SVNRepository.cxx SVNRepository.cxx
SVNDirectory.cxx SVNDirectory.cxx
SVNReportParser.cxx SVNReportParser.cxx
) )
if (NOT ENABLE_CURL)
list(APPEND SOURCES HTTPContentDecode.cxx)
list(APPEND HEADERS HTTPContentDecode.hxx)
endif()
simgear_component(io io "${SOURCES}" "${HEADERS}") simgear_component(io io "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS) if(ENABLE_TESTS)
+4 -4
View File
@@ -193,7 +193,7 @@ public:
{ {
if (tagStack.empty()) { if (tagStack.empty()) {
if (strcmp(name, DAV_MULTISTATUS_TAG)) { if (strcmp(name, DAV_MULTISTATUS_TAG)) {
SG_LOG(SG_TERRASYNC, SG_WARN, "root element is not " << SG_LOG(SG_IO, SG_WARN, "root element is not " <<
DAV_MULTISTATUS_TAG << ", got:" << name); DAV_MULTISTATUS_TAG << ", got:" << name);
} else { } else {
@@ -202,7 +202,7 @@ public:
// not at the root element // not at the root element
if (tagStack.back() == DAV_MULTISTATUS_TAG) { if (tagStack.back() == DAV_MULTISTATUS_TAG) {
if (strcmp(name, DAV_RESPONSE_TAG)) { if (strcmp(name, DAV_RESPONSE_TAG)) {
SG_LOG(SG_TERRASYNC, SG_WARN, "multistatus child is not response: saw:" SG_LOG(SG_IO, SG_WARN, "multistatus child is not response: saw:"
<< name); << name);
} }
} }
@@ -362,7 +362,7 @@ void DAVMultiStatus::parseXML(const char* data, int size)
} }
if (!XML_Parse(_d->xmlParser, data, size, false)) { if (!XML_Parse(_d->xmlParser, data, size, false)) {
SG_LOG(SG_TERRASYNC, SG_WARN, "DAV parse error:" << XML_ErrorString(XML_GetErrorCode(_d->xmlParser)) SG_LOG(SG_IO, SG_WARN, "DAV parse error:" << XML_ErrorString(XML_GetErrorCode(_d->xmlParser))
<< " at line:" << XML_GetCurrentLineNumber(_d->xmlParser) << " at line:" << XML_GetCurrentLineNumber(_d->xmlParser)
<< " column " << XML_GetCurrentColumnNumber(_d->xmlParser)); << " column " << XML_GetCurrentColumnNumber(_d->xmlParser));
@@ -376,7 +376,7 @@ void DAVMultiStatus::finishParse()
{ {
if (_d->parserInited) { if (_d->parserInited) {
if (!XML_Parse(_d->xmlParser, NULL, 0, true)) { if (!XML_Parse(_d->xmlParser, NULL, 0, true)) {
SG_LOG(SG_TERRASYNC, SG_WARN, "DAV parse error:" << XML_ErrorString(XML_GetErrorCode(_d->xmlParser)) SG_LOG(SG_IO, SG_WARN, "DAV parse error:" << XML_ErrorString(XML_GetErrorCode(_d->xmlParser))
<< " at line:" << XML_GetCurrentLineNumber(_d->xmlParser) << " at line:" << XML_GetCurrentLineNumber(_d->xmlParser)
<< " column " << XML_GetCurrentColumnNumber(_d->xmlParser)); << " column " << XML_GetCurrentColumnNumber(_d->xmlParser));
_d->valid = false; _d->valid = false;
+29 -275
View File
@@ -21,7 +21,6 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
// //
#include "HTTPClient.hxx" #include "HTTPClient.hxx"
#include "HTTPFileRequest.hxx" #include "HTTPFileRequest.hxx"
@@ -36,16 +35,8 @@
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
#include <simgear/simgear_config.h>
#if defined(ENABLE_CURL)
#include <curl/multi.h>
#else
#include <simgear/io/HTTPContentDecode.hxx>
#endif
#include <simgear/io/sg_netChat.hxx> #include <simgear/io/sg_netChat.hxx>
#include <simgear/io/HTTPContentDecode.hxx>
#include <simgear/misc/strutils.hxx> #include <simgear/misc/strutils.hxx>
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
@@ -77,24 +68,17 @@ typedef std::list<Request_ptr> RequestList;
class Client::ClientPrivate class Client::ClientPrivate
{ {
public: public:
#if defined(ENABLE_CURL)
CURLM* curlMulti;
bool haveActiveRequests;
#else
NetChannelPoller poller;
// connections by host (potentially more than one)
ConnectionDict connections;
#endif
std::string userAgent; std::string userAgent;
std::string proxy; std::string proxy;
int proxyPort; int proxyPort;
std::string proxyAuth; std::string proxyAuth;
NetChannelPoller poller;
unsigned int maxConnections; unsigned int maxConnections;
RequestList pendingRequests; RequestList pendingRequests;
// connections by host (potentially more than one)
ConnectionDict connections;
SGTimeStamp timeTransferSample; SGTimeStamp timeTransferSample;
unsigned int bytesTransferred; unsigned int bytesTransferred;
@@ -102,15 +86,13 @@ public:
uint64_t totalBytesDownloaded; uint64_t totalBytesDownloaded;
}; };
#if !defined(ENABLE_CURL)
class Connection : public NetChat class Connection : public NetChat
{ {
public: public:
Connection(Client* pr, const std::string& conId) : Connection(Client* pr) :
client(pr), client(pr),
state(STATE_CLOSED), state(STATE_CLOSED),
port(DEFAULT_HTTP_PORT), port(DEFAULT_HTTP_PORT)
connectionId(conId)
{ {
} }
@@ -141,11 +123,6 @@ public:
virtual void handleError(int error) virtual void handleError(int error)
{ {
const char* errStr = strerror(error); const char* errStr = strerror(error);
SG_LOG(SG_IO, SG_WARN, "HTTP Connection handleError:" << error << " ("
<< errStr << ")");
debugDumpRequests();
if (!activeRequest) if (!activeRequest)
{ {
// connection level failure, eg name lookup or routing // connection level failure, eg name lookup or routing
@@ -174,11 +151,6 @@ public:
state = STATE_SOCKET_ERROR; state = STATE_SOCKET_ERROR;
} }
void handleTimeout()
{
handleError(ETIMEDOUT);
}
virtual void handleClose() virtual void handleClose()
{ {
NetChat::handleClose(); NetChat::handleClose();
@@ -191,13 +163,6 @@ public:
state = STATE_CLOSED; state = STATE_CLOSED;
responseComplete(); responseComplete();
} else { } else {
if (state == STATE_WAITING_FOR_RESPONSE) {
assert(!sentRequests.empty());
sentRequests.front()->setFailure(500, "server closed connection unexpectedly");
// no active request, but don't restore the front sent one
sentRequests.erase(sentRequests.begin());
}
if (activeRequest) { if (activeRequest) {
activeRequest->setFailure(500, "server closed connection"); activeRequest->setFailure(500, "server closed connection");
// remove the failed request from sentRequests, so it does // remove the failed request from sentRequests, so it does
@@ -225,6 +190,19 @@ public:
sentRequests.clear(); sentRequests.clear();
} }
void handleTimeout()
{
NetChat::handleError(ETIMEDOUT);
if (activeRequest) {
SG_LOG(SG_IO, SG_DEBUG, "HTTP socket timeout");
activeRequest->setFailure(ETIMEDOUT, "socket timeout");
activeRequest = NULL;
_contentDecoder.reset();
}
state = STATE_SOCKET_ERROR;
}
void queueRequest(const Request_ptr& r) void queueRequest(const Request_ptr& r)
{ {
queuedRequests.push_back(r); queuedRequests.push_back(r);
@@ -241,7 +219,6 @@ public:
activeRequest->responseStart(buffer); activeRequest->responseStart(buffer);
} catch (sg_exception& e) { } catch (sg_exception& e) {
handleError(EIO); handleError(EIO);
return;
} }
state = STATE_GETTING_HEADERS; state = STATE_GETTING_HEADERS;
@@ -361,7 +338,9 @@ public:
} }
} }
SG_LOG(SG_IO, SG_DEBUG, "con:" << connectionId << " did start request:" << r->url()); // SG_LOG(SG_IO, SG_INFO, "did start request:" << r->url() <<
// "\n\t @ " << reinterpret_cast<void*>(r.ptr()) <<
// "\n\t on connection " << this);
// successfully sent, remove from queue, and maybe send the next // successfully sent, remove from queue, and maybe send the next
queuedRequests.pop_front(); queuedRequests.pop_front();
sentRequests.push_back(r); sentRequests.push_back(r);
@@ -426,23 +405,21 @@ public:
bool hasIdleTimeout() const bool hasIdleTimeout() const
{ {
if ((state != STATE_IDLE) && (state != STATE_CLOSED)) { if (state != STATE_IDLE) {
return false; return false;
} }
assert(sentRequests.empty()); assert(sentRequests.empty());
bool isTimedOut = (idleTime.elapsedMSec() > (1000 * 10)); // 10 seconds return idleTime.elapsedMSec() > 1000 * 10; // ten seconds
return isTimedOut;
} }
bool hasErrorTimeout() const bool hasErrorTimeout() const
{ {
if ((state == STATE_IDLE) || (state == STATE_CLOSED)) { if (state == STATE_IDLE) {
return false; return false;
} }
bool isTimedOut = (idleTime.elapsedMSec() > (1000 * 30)); // 30 seconds return idleTime.elapsedMSec() > (1000 * 30); // 30 seconds
return isTimedOut;
} }
bool hasError() const bool hasError() const
@@ -459,37 +436,17 @@ public:
{ {
return !queuedRequests.empty() || !sentRequests.empty(); return !queuedRequests.empty() || !sentRequests.empty();
} }
void debugDumpRequests() const
{
SG_LOG(SG_IO, SG_DEBUG, "requests for:" << host << ":" << port << " (conId=" << connectionId
<< "; state=" << state << ")");
if (activeRequest) {
SG_LOG(SG_IO, SG_DEBUG, "\tactive:" << activeRequest->url());
} else {
SG_LOG(SG_IO, SG_DEBUG, "\tNo active request");
}
BOOST_FOREACH(Request_ptr req, sentRequests) {
SG_LOG(SG_IO, SG_DEBUG, "\tsent:" << req->url());
}
BOOST_FOREACH(Request_ptr req, queuedRequests) {
SG_LOG(SG_IO, SG_DEBUG, "\tqueued:" << req->url());
}
}
private: private:
bool connectToHost() bool connectToHost()
{ {
SG_LOG(SG_IO, SG_DEBUG, "HTTP connecting to " << host << ":" << port); SG_LOG(SG_IO, SG_DEBUG, "HTTP connecting to " << host << ":" << port);
if (!open()) { if (!open()) {
SG_LOG(SG_IO, SG_WARN, "HTTP::Connection: connectToHost: open() failed"); SG_LOG(SG_ALL, SG_WARN, "HTTP::Connection: connectToHost: open() failed");
return false; return false;
} }
if (connect(host.c_str(), port) != 0) { if (connect(host.c_str(), port) != 0) {
SG_LOG(SG_IO, SG_WARN, "HTTP::Connection: connectToHost: connect() failed");
return false; return false;
} }
@@ -630,6 +587,7 @@ private:
// notify request after we change state, so this connection is idle // notify request after we change state, so this connection is idle
// if completion triggers other requests (which is likely) // if completion triggers other requests (which is likely)
// SG_LOG(SG_IO, SG_INFO, "*** responseComplete:" << activeRequest->url());
completedRequest->responseComplete(); completedRequest->responseComplete();
client->requestFinished(this); client->requestFinished(this);
@@ -663,9 +621,7 @@ private:
RequestList sentRequests; RequestList sentRequests;
ContentDecoder _contentDecoder; ContentDecoder _contentDecoder;
std::string connectionId;
}; };
#endif // of !ENABLE_CURL
Client::Client() : Client::Client() :
d(new ClientPrivate) d(new ClientPrivate)
@@ -678,22 +634,10 @@ Client::Client() :
d->totalBytesDownloaded = 0; d->totalBytesDownloaded = 0;
setUserAgent("SimGear-" SG_STRINGIZE(SIMGEAR_VERSION)); setUserAgent("SimGear-" SG_STRINGIZE(SIMGEAR_VERSION));
#if defined(ENABLE_CURL)
static bool didInitCurlGlobal = false;
if (!didInitCurlGlobal) {
curl_global_init(CURL_GLOBAL_ALL);
didInitCurlGlobal = true;
}
d->curlMulti = curl_multi_init();
#endif
} }
Client::~Client() Client::~Client()
{ {
#if defined(ENABLE_CURL)
curl_multi_cleanup(d->curlMulti);
#endif
} }
void Client::setMaxConnections(unsigned int maxCon) void Client::setMaxConnections(unsigned int maxCon)
@@ -703,47 +647,10 @@ void Client::setMaxConnections(unsigned int maxCon)
} }
d->maxConnections = maxCon; d->maxConnections = maxCon;
#if defined(ENABLE_CURL)
curl_multi_setopt(d->curlMulti, CURLMOPT_MAXCONNECTS, (long) maxCon);
#endif
} }
void Client::update(int waitTimeout) void Client::update(int waitTimeout)
{ {
#if defined(ENABLE_CURL)
int remainingActive, messagesInQueue;
curl_multi_perform(d->curlMulti, &remainingActive);
d->haveActiveRequests = (remainingActive > 0);
CURLMsg* msg;
while ((msg = curl_multi_info_read(d->curlMulti, &messagesInQueue))) {
if (msg->msg == CURLMSG_DONE) {
Request* req;
CURL *e = msg->easy_handle;
curl_easy_getinfo(e, CURLINFO_PRIVATE, &req);
long responseCode;
curl_easy_getinfo(e, CURLINFO_RESPONSE_CODE, &responseCode);
if (msg->data.result == 0) {
req->responseComplete();
} else {
fprintf(stderr, "Result: %d - %s\n",
msg->data.result, curl_easy_strerror(msg->data.result));
req->setFailure(msg->data.result, curl_easy_strerror(msg->data.result));
}
curl_multi_remove_handle(d->curlMulti, e);
// balance the reference we take in makeRequest
SGReferenced::put(req);
curl_easy_cleanup(e);
}
else {
SG_LOG(SG_IO, SG_ALERT, "CurlMSG:" << msg->msg);
}
} // of curl message processing loop
#else
if (!d->poller.hasChannels() && (waitTimeout > 0)) { if (!d->poller.hasChannels() && (waitTimeout > 0)) {
SGTimeStamp::sleepForMSec(waitTimeout); SGTimeStamp::sleepForMSec(waitTimeout);
} else { } else {
@@ -789,7 +696,6 @@ void Client::update(int waitTimeout)
makeRequest(req); makeRequest(req);
} }
} }
#endif
} }
void Client::makeRequest(const Request_ptr& r) void Client::makeRequest(const Request_ptr& r)
@@ -802,82 +708,6 @@ void Client::makeRequest(const Request_ptr& r)
return; return;
} }
#if defined(ENABLE_CURL)
CURL* curlRequest = curl_easy_init();
curl_easy_setopt(curlRequest, CURLOPT_URL, r->url().c_str());
// manually increase the ref count of the request
SGReferenced::get(r.get());
curl_easy_setopt(curlRequest, CURLOPT_PRIVATE, r.get());
// disable built-in libCurl progress feedback
curl_easy_setopt(curlRequest, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curlRequest, CURLOPT_WRITEFUNCTION, requestWriteCallback);
curl_easy_setopt(curlRequest, CURLOPT_WRITEDATA, r.get());
curl_easy_setopt(curlRequest, CURLOPT_HEADERFUNCTION, requestHeaderCallback);
curl_easy_setopt(curlRequest, CURLOPT_HEADERDATA, r.get());
curl_easy_setopt(curlRequest, CURLOPT_USERAGENT, d->userAgent.c_str());
if (!d->proxy.empty()) {
curl_easy_setopt(curlRequest, CURLOPT_PROXY, d->proxy.c_str());
curl_easy_setopt(curlRequest, CURLOPT_PROXYPORT, d->proxyPort);
if (!d->proxyAuth.empty()) {
curl_easy_setopt(curlRequest, CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
curl_easy_setopt(curlRequest, CURLOPT_PROXYUSERPWD, d->proxyAuth.c_str());
}
}
std::string method = boost::to_lower_copy(r->method());
if (method == "get") {
curl_easy_setopt(curlRequest, CURLOPT_HTTPGET, 1);
} else if (method == "put") {
curl_easy_setopt(curlRequest, CURLOPT_PUT, 1);
curl_easy_setopt(curlRequest, CURLOPT_UPLOAD, 1);
} else if (method == "post") {
// see http://curl.haxx.se/libcurl/c/CURLOPT_POST.html
curl_easy_setopt(curlRequest, CURLOPT_HTTPPOST, 1);
std::string q = r->query().substr(1);
curl_easy_setopt(curlRequest, CURLOPT_COPYPOSTFIELDS, q.c_str());
// reset URL to exclude query pieces
std::string urlWithoutQuery = r->url();
std::string::size_type queryPos = urlWithoutQuery.find('?');
urlWithoutQuery.resize(queryPos);
curl_easy_setopt(curlRequest, CURLOPT_URL, urlWithoutQuery.c_str());
} else {
curl_easy_setopt(curlRequest, CURLOPT_CUSTOMREQUEST, r->method().c_str());
}
struct curl_slist* headerList = NULL;
if (r->hasBodyData() && (method != "post")) {
curl_easy_setopt(curlRequest, CURLOPT_UPLOAD, 1);
curl_easy_setopt(curlRequest, CURLOPT_INFILESIZE, r->bodyLength());
curl_easy_setopt(curlRequest, CURLOPT_READFUNCTION, requestReadCallback);
curl_easy_setopt(curlRequest, CURLOPT_READDATA, r.get());
std::string h = "Content-Type:" + r->bodyType();
headerList = curl_slist_append(headerList, h.c_str());
}
StringMap::const_iterator it;
for (it = r->requestHeaders().begin(); it != r->requestHeaders().end(); ++it) {
std::string h = it->first + ": " + it->second;
headerList = curl_slist_append(headerList, h.c_str());
}
if (headerList != NULL) {
curl_easy_setopt(curlRequest, CURLOPT_HTTPHEADER, headerList);
}
curl_multi_add_handle(d->curlMulti, curlRequest);
d->haveActiveRequests = true;
// FIXME - premature?
r->requestStart();
#else
if( r->url().find("http://") != 0 ) { if( r->url().find("http://") != 0 ) {
r->setFailure(EINVAL, "only HTTP protocol is supported"); r->setFailure(EINVAL, "only HTTP protocol is supported");
return; return;
@@ -935,7 +765,7 @@ void Client::makeRequest(const Request_ptr& r)
// allocate a new connection object // allocate a new connection object
if (!con) { if (!con) {
con = new Connection(this, connectionId); con = new Connection(this);
con->setServer(host, port); con->setServer(host, port);
d->poller.addChannel(con); d->poller.addChannel(con);
d->connections.insert(d->connections.end(), d->connections.insert(d->connections.end(),
@@ -943,7 +773,6 @@ void Client::makeRequest(const Request_ptr& r)
} }
con->queueRequest(r); con->queueRequest(r);
#endif
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -999,16 +828,12 @@ void Client::setProxy( const std::string& proxy,
bool Client::hasActiveRequests() const bool Client::hasActiveRequests() const
{ {
#if defined(ENABLE_CURL)
return d->haveActiveRequests;
#else
ConnectionDict::const_iterator it = d->connections.begin(); ConnectionDict::const_iterator it = d->connections.begin();
for (; it != d->connections.end(); ++it) { for (; it != d->connections.end(); ++it) {
if (it->second->isActive()) return true; if (it->second->isActive()) return true;
} }
return false; return false;
#endif
} }
void Client::receivedBytes(unsigned int count) void Client::receivedBytes(unsigned int count)
@@ -1048,77 +873,6 @@ uint64_t Client::totalBytesDownloaded() const
return d->totalBytesDownloaded; return d->totalBytesDownloaded;
} }
size_t Client::requestWriteCallback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t byteSize = size * nmemb;
Request* req = static_cast<Request*>(userdata);
req->processBodyBytes(ptr, byteSize);
return byteSize;
}
size_t Client::requestReadCallback(char *ptr, size_t size, size_t nmemb, void *userdata)
{
size_t maxBytes = size * nmemb;
Request* req = static_cast<Request*>(userdata);
size_t actualBytes = req->getBodyData(ptr, 0, maxBytes);
return actualBytes;
}
size_t Client::requestHeaderCallback(char *rawBuffer, size_t size, size_t nitems, void *userdata)
{
size_t byteSize = size * nitems;
Request* req = static_cast<Request*>(userdata);
std::string h = strutils::simplify(std::string(rawBuffer, byteSize));
if (req->readyState() == HTTP::Request::OPENED) {
req->responseStart(h);
return byteSize;
}
if (h.empty()) {
// got a 100-continue reponse; restart
if (req->responseCode() == 100) {
req->setReadyState(HTTP::Request::OPENED);
return byteSize;
}
req->responseHeadersComplete();
return byteSize;
}
if (req->responseCode() == 100) {
return byteSize; // skip headers associated with 100-continue status
}
size_t colonPos = h.find(':');
if (colonPos == std::string::npos) {
SG_LOG(SG_IO, SG_WARN, "malformed HTTP response header:" << h);
return byteSize;
}
std::string key = strutils::simplify(h.substr(0, colonPos));
std::string lkey = boost::to_lower_copy(key);
std::string value = strutils::strip(h.substr(colonPos + 1));
req->responseHeader(lkey, value);
return byteSize;
}
void Client::debugDumpRequests()
{
#if defined(ENABLE_CURL)
#else
SG_LOG(SG_IO, SG_INFO, "== HTTP connection dump");
ConnectionDict::iterator it = d->connections.begin();
for (; it != d->connections.end(); ++it) {
it->second->debugDumpRequests();
}
SG_LOG(SG_IO, SG_INFO, "==");
#endif
}
} // of namespace HTTP } // of namespace HTTP
} // of namespace simgear } // of namespace simgear
-7
View File
@@ -98,14 +98,7 @@ public:
* monitoring * monitoring
*/ */
uint64_t totalBytesDownloaded() const; uint64_t totalBytesDownloaded() const;
void debugDumpRequests();
private: private:
// libCurl callbacks
static size_t requestWriteCallback(char *ptr, size_t size, size_t nmemb, void *userdata);
static size_t requestReadCallback(char *ptr, size_t size, size_t nmemb, void *userdata);
static size_t requestHeaderCallback(char *buffer, size_t size, size_t nitems, void *userdata);
void requestFinished(Connection* con); void requestFinished(Connection* con);
void receivedBytes(unsigned int count); void receivedBytes(unsigned int count);
+2 -9
View File
@@ -133,25 +133,19 @@ void Request::responseStart(const std::string& r)
const int maxSplit = 2; // HTTP/1.1 nnn reason-string const int maxSplit = 2; // HTTP/1.1 nnn reason-string
string_list parts = strutils::split(r, NULL, maxSplit); string_list parts = strutils::split(r, NULL, maxSplit);
if (parts.size() != 3) { if (parts.size() != 3) {
throw sg_io_exception("bad HTTP response:" + r); throw sg_io_exception("bad HTTP response");
} }
_responseVersion = decodeHTTPVersion(parts[0]); _responseVersion = decodeHTTPVersion(parts[0]);
_responseStatus = strutils::to_int(parts[1]); _responseStatus = strutils::to_int(parts[1]);
_responseReason = parts[2]; _responseReason = parts[2];
setReadyState(STATUS_RECEIVED);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Request::responseHeader(const std::string& key, const std::string& value) void Request::responseHeader(const std::string& key, const std::string& value)
{ {
if( key == "connection" ) { if( key == "connection" )
_willClose = (value.find("close") != std::string::npos); _willClose = (value.find("close") != std::string::npos);
} else if (key == "content-length") {
int sz = strutils::to_int(value);
setResponseLength(sz);
}
_responseHeaders[key] = value; _responseHeaders[key] = value;
} }
@@ -325,7 +319,6 @@ unsigned int Request::responseLength() const
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Request::setFailure(int code, const std::string& reason) void Request::setFailure(int code, const std::string& reason)
{ {
SG_LOG(SG_IO, SG_WARN, "HTTP request: set failure:" << code << " reason " << reason);
_responseStatus = code; _responseStatus = code;
_responseReason = reason; _responseReason = reason;
-1
View File
@@ -50,7 +50,6 @@ public:
{ {
UNSENT = 0, UNSENT = 0,
OPENED, OPENED,
STATUS_RECEIVED,
HEADERS_RECEIVED, HEADERS_RECEIVED,
LOADING, LOADING,
DONE, DONE,
+7 -13
View File
@@ -96,14 +96,14 @@ void SVNDirectory::parseCache()
LineState lineState = LINESTATE_HREF; LineState lineState = LINESTATE_HREF;
std::ifstream file(p.c_str()); std::ifstream file(p.c_str());
if (!file.is_open()) { if (!file.is_open()) {
SG_LOG(SG_TERRASYNC, SG_WARN, "unable to open cache file for reading:" << p); SG_LOG(SG_IO, SG_WARN, "unable to open cache file for reading:" << p);
return; return;
} }
bool doneSelf = false; bool doneSelf = false;
file.getline(href, 1024); file.getline(href, 1024);
if (strcmp(CACHE_VERSION_4_TOKEN, href)) { if (strcmp(CACHE_VERSION_4_TOKEN, href)) {
SG_LOG(SG_TERRASYNC, SG_WARN, "invalid cache file [missing header token]:" << p << " '" << href << "'"); SG_LOG(SG_IO, SG_WARN, "invalid cache file [missing header token]:" << p << " '" << href << "'");
return; return;
} }
@@ -183,7 +183,7 @@ void SVNDirectory::writeCache()
void SVNDirectory::setBaseUrl(const string& url) void SVNDirectory::setBaseUrl(const string& url)
{ {
if (_parent) { if (_parent) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "setting base URL on non-root directory " << url); SG_LOG(SG_IO, SG_ALERT, "setting base URL on non-root directory " << url);
return; return;
} }
@@ -239,6 +239,7 @@ void SVNDirectory::deleteChildByName(const std::string& nm)
{ {
DAVResource* child = dav->childWithName(nm); DAVResource* child = dav->childWithName(nm);
if (!child) { if (!child) {
// std::cerr << "ZZZ: deleteChildByName: unknown:" << nm << std::endl;
return; return;
} }
@@ -246,24 +247,17 @@ void SVNDirectory::deleteChildByName(const std::string& nm)
if (child->isCollection()) { if (child->isCollection()) {
Dir d(path); Dir d(path);
bool ok = d.remove(true); d.remove(true);
if (!ok) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "SVNDirectory::deleteChildByName: failed to remove dir:"
<< nm << " at path:\n\t" << path);
}
DirectoryList::iterator it = findChildDir(nm); DirectoryList::iterator it = findChildDir(nm);
if (it != _children.end()) { if (it != _children.end()) {
SVNDirectory* c = *it; SVNDirectory* c = *it;
// std::cout << "YYY: deleting SVNDirectory for:" << nm << std::endl;
delete c; delete c;
_children.erase(it); _children.erase(it);
} }
} else { } else {
bool ok = path.remove(); path.remove();
if (!ok) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "SVNDirectory::deleteChildByName: failed to remove path:" << nm
<< " at path:\n\t" << path);
}
} }
dav->removeChild(child); dav->removeChild(child);
+5 -8
View File
@@ -73,7 +73,7 @@ public:
void updateFailed(HTTP::Request* req, SVNRepository::ResultCode err) void updateFailed(HTTP::Request* req, SVNRepository::ResultCode err)
{ {
SG_LOG(SG_TERRASYNC, SG_WARN, "SVN: failed to update from:" << req->url() SG_LOG(SG_IO, SG_WARN, "SVN: failed to update from:" << req->url()
<< "\n(repository:" << p->baseUrl() << ")"); << "\n(repository:" << p->baseUrl() << ")");
isUpdating = false; isUpdating = false;
status = err; status = err;
@@ -120,7 +120,6 @@ namespace { // anonmouse
Request(repo->baseUrl, "PROPFIND"), Request(repo->baseUrl, "PROPFIND"),
_repo(repo) _repo(repo)
{ {
assert(repo);
requestHeader("Depth") = "0"; requestHeader("Depth") = "0";
setBodyData( PROPFIND_REQUEST_BODY, setBodyData( PROPFIND_REQUEST_BODY,
"application/xml; charset=\"utf-8\"" ); "application/xml; charset=\"utf-8\"" );
@@ -134,13 +133,11 @@ namespace { // anonmouse
} else if (responseCode() == 404) { } else if (responseCode() == 404) {
_repo->propFindFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND); _repo->propFindFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND);
} else { } else {
SG_LOG(SG_TERRASYNC, SG_WARN, "request for:" << url() << SG_LOG(SG_IO, SG_WARN, "request for:" << url() <<
" return code " << responseCode()); " return code " << responseCode());
_repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET); _repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET);
_repo = NULL; _repo = NULL;
} }
Request::responseHeadersComplete();
} }
virtual void onDone() virtual void onDone()
@@ -231,7 +228,7 @@ protected:
_repo->updateFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND); _repo->updateFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND);
_failed = true; _failed = true;
} else { } else {
SG_LOG(SG_TERRASYNC, SG_WARN, "SVN: request for:" << url() << SG_LOG(SG_IO, SG_WARN, "SVN: request for:" << url() <<
" got HTTP status " << responseCode()); " got HTTP status " << responseCode());
_repo->updateFailed(this, SVNRepository::SVN_ERROR_HTTP); _repo->updateFailed(this, SVNRepository::SVN_ERROR_HTTP);
_failed = true; _failed = true;
@@ -331,7 +328,7 @@ void SVNRepository::update()
} }
if (_d->targetRevision == rootDir()->cachedRevision()) { if (_d->targetRevision == rootDir()->cachedRevision()) {
SG_LOG(SG_TERRASYNC, SG_DEBUG, baseUrl() << " in sync at version " << _d->targetRevision); SG_LOG(SG_IO, SG_DEBUG, baseUrl() << " in sync at version " << _d->targetRevision);
_d->isUpdating = false; _d->isUpdating = false;
return; return;
} }
@@ -375,7 +372,7 @@ void SVNRepoPrivate::propFindComplete(HTTP::Request* req, DAVCollection* c)
void SVNRepoPrivate::propFindFailed(HTTP::Request *req, SVNRepository::ResultCode err) void SVNRepoPrivate::propFindFailed(HTTP::Request *req, SVNRepository::ResultCode err)
{ {
if (err != SVNRepository::SVN_ERROR_NOT_FOUND) { if (err != SVNRepository::SVN_ERROR_NOT_FOUND) {
SG_LOG(SG_TERRASYNC, SG_WARN, "PropFind failed for:" << req->url()); SG_LOG(SG_IO, SG_WARN, "PropFind failed for:" << req->url());
} }
isUpdating = false; isUpdating = false;
-12
View File
@@ -227,13 +227,6 @@ void NetChannel::handleAccept (void) {
void NetChannel::handleError (int error) void NetChannel::handleError (int error)
{ {
if (error == EINPROGRESS) {
// this shoudl never happen, because we should use isNonBlocking to check
// such error codes.
SG_LOG(SG_IO, SG_WARN, "Got EINPROGRESS at NetChannel::handleError: suggests broken logic somewhere else");
return; // not an actual error, don't warn
}
// warn about address lookup failures seperately, don't warn again. // warn about address lookup failures seperately, don't warn again.
// (and we (ab-)use ENOENT to mean 'name not found'. // (and we (ab-)use ENOENT to mean 'name not found'.
if (error != ENOENT) { if (error != ENOENT) {
@@ -258,11 +251,6 @@ NetChannelPoller::removeChannel(NetChannel* channel)
assert(channel->poller == this); assert(channel->poller == this);
channel->poller = NULL; channel->poller = NULL;
// portability: MSVC throws assertion failure when empty
if (channels.empty()) {
return;
}
ChannelList::iterator it = channels.begin(); ChannelList::iterator it = channels.begin();
for (; it != channels.end(); ++it) { for (; it != channels.end(); ++it) {
if (*it == channel) { if (*it == channel) {
-1
View File
@@ -27,7 +27,6 @@
#include <cstring> #include <cstring>
#include <cstdlib> #include <cstdlib>
#include <algorithm>
namespace simgear { namespace simgear {
-1
View File
@@ -32,7 +32,6 @@
#include <cstring> #include <cstring>
#include <cstdlib> // for atoi #include <cstdlib> // for atoi
#include <algorithm>
using std::string; using std::string;
+21 -146
View File
@@ -3,23 +3,15 @@
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <errno.h>
#include <boost/algorithm/string/case_conv.hpp> #include <boost/algorithm/string/case_conv.hpp>
#include <simgear/simgear_config.h>
#include "HTTPClient.hxx" #include "HTTPClient.hxx"
#include "HTTPRequest.hxx" #include "HTTPRequest.hxx"
#include <simgear/io/sg_netChat.hxx> #include <simgear/io/sg_netChat.hxx>
#include <simgear/misc/strutils.hxx> #include <simgear/misc/strutils.hxx>
#include <simgear/timing/timestamp.hxx> #include <simgear/timing/timestamp.hxx>
#include <simgear/debug/logstream.hxx>
#if defined(ENABLE_CURL)
#include <curl/multi.h>
#endif
using std::cout; using std::cout;
using std::cerr; using std::cerr;
@@ -64,8 +56,7 @@ public:
TestRequest(const std::string& url, const std::string method = "GET") : TestRequest(const std::string& url, const std::string method = "GET") :
HTTP::Request(url, method), HTTP::Request(url, method),
complete(false), complete(false)
failed(false)
{ {
} }
@@ -91,7 +82,6 @@ protected:
virtual void responseHeader(const string& header, const string& value) virtual void responseHeader(const string& header, const string& value)
{ {
Request::responseHeader(header, value);
headers[header] = value; headers[header] = value;
} }
}; };
@@ -151,7 +141,7 @@ public:
string::size_type colonPos = buffer.find(':'); string::size_type colonPos = buffer.find(':');
if (colonPos == string::npos) { if (colonPos == string::npos) {
cerr << "test malformed HTTP response header:" << buffer << endl; cerr << "malformed HTTP response header:" << buffer << endl;
buffer.clear(); buffer.clear();
return; return;
} }
@@ -187,6 +177,7 @@ public:
void receivedRequestHeaders() void receivedRequestHeaders()
{ {
state = STATE_IDLE; state = STATE_IDLE;
if (path == "/test1") { if (path == "/test1") {
string contentStr(BODY1); string contentStr(BODY1);
stringstream d; stringstream d;
@@ -246,7 +237,7 @@ public:
} }
if (requestHeaders["Proxy-Authorization"] != string()) { if (requestHeaders["Proxy-Authorization"] != string()) {
sendErrorResponse(401, false, "bad auth, not empty"); // shouldn't supply auth sendErrorResponse(401, false, "bad auth"); // shouldn't supply auth
} }
sendBody2(); sendBody2();
@@ -256,28 +247,8 @@ public:
sendErrorResponse(400, true, "bad destination"); sendErrorResponse(400, true, "bad destination");
} }
string credentials = requestHeaders["Proxy-Authorization"]; if (requestHeaders["Proxy-Authorization"] != "ABCDEF") {
if (credentials.substr(0, 5) != "Basic") { sendErrorResponse(401, false, "bad auth"); // forbidden
// request basic auth
stringstream d;
d << "HTTP/1.1 " << 407 << " " << reasonForCode(407) << "\r\n";
d << "WWW-Authenticate: Basic real=\"simgear\"\r\n";
d << "\r\n"; // final CRLF to terminate the headers
push(d.str().c_str());
return;
}
std::vector<unsigned char> userAndPass;
strutils::decodeBase64(credentials.substr(6), userAndPass);
std::string decodedUserPass((char*) userAndPass.data(), userAndPass.size());
if (decodedUserPass != "johndoe:swordfish") {
std::map<string, string>::const_iterator it;
for (it = requestHeaders.begin(); it != requestHeaders.end(); ++it) {
cerr << "header:" << it->first << " = " << it->second << endl;
}
sendErrorResponse(401, false, "bad auth, not as set"); // forbidden
} }
sendBody2(); sendBody2();
@@ -301,12 +272,6 @@ public:
d << contentStr; d << contentStr;
push(d.str().c_str()); push(d.str().c_str());
closeAfterSending(); closeAfterSending();
} else if (path == "/test_abrupt_close") {
// simulate server doing socket close before sending any
// response - this used to cause a TerraSync failure since we
// would get stuck restarting the request
closeAfterSending();
} else if (path == "/test_args") { } else if (path == "/test_args") {
if ((args["foo"] != "abc") || (args["bar"] != "1234") || (args["username"] != "johndoe")) { if ((args["foo"] != "abc") || (args["bar"] != "1234") || (args["username"] != "johndoe")) {
sendErrorResponse(400, true, "bad arguments"); sendErrorResponse(400, true, "bad arguments");
@@ -327,16 +292,6 @@ public:
return; return;
} }
requestContentLength = strutils::to_int(requestHeaders["Content-Length"]);
setByteCount(requestContentLength);
state = STATE_REQUEST_BODY;
} else if ((path == "/test_put") || (path == "/test_create")) {
if (requestHeaders["Content-Type"] != "x-application/foobar") {
cerr << "bad content type: '" << requestHeaders["Content-Type"] << "'" << endl;
sendErrorResponse(400, true, "bad content type");
return;
}
requestContentLength = strutils::to_int(requestHeaders["Content-Length"]); requestContentLength = strutils::to_int(requestHeaders["Content-Length"]);
setByteCount(requestContentLength); setByteCount(requestContentLength);
state = STATE_REQUEST_BODY; state = STATE_REQUEST_BODY;
@@ -368,34 +323,9 @@ public:
d << "HTTP/1.1 " << 204 << " " << reasonForCode(204) << "\r\n"; d << "HTTP/1.1 " << 204 << " " << reasonForCode(204) << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers d << "\r\n"; // final CRLF to terminate the headers
push(d.str().c_str()); push(d.str().c_str());
} else if (path == "/test_put") {
std::cerr << "sending PUT response" << std::endl;
COMPARE(buffer, BODY3); cerr << "sent 204 response ok" << endl;
stringstream d;
d << "HTTP/1.1 " << 204 << " " << reasonForCode(204) << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
push(d.str().c_str());
} else if (path == "/test_create") {
std::cerr << "sending create response" << std::endl;
std::string entityStr = "http://localhost:2000/something.txt";
COMPARE(buffer, BODY3);
stringstream d;
d << "HTTP/1.1 " << 201 << " " << reasonForCode(201) << "\r\n";
d << "Location:" << entityStr << "\r\n";
d << "Content-Length:" << entityStr.size() << "\r\n";
d << "\r\n"; // final CRLF to terminate the headers
d << entityStr;
push(d.str().c_str());
} else {
std::cerr << "weird URL " << path << std::endl;
sendErrorResponse(400, true, "bad URL:" + path);
} }
buffer.clear();
} }
void sendBody2() void sendBody2()
@@ -411,8 +341,6 @@ public:
void sendErrorResponse(int code, bool close, string content) void sendErrorResponse(int code, bool close, string content)
{ {
cerr << "sending error " << code << " for " << path << endl; cerr << "sending error " << code << " for " << path << endl;
cerr << "\tcontent:" << content << endl;
stringstream headerData; stringstream headerData;
headerData << "HTTP/1.1 " << code << " " << reasonForCode(code) << "\r\n"; headerData << "HTTP/1.1 " << code << " " << reasonForCode(code) << "\r\n";
headerData << "Content-Length:" << content.size() << "\r\n"; headerData << "Content-Length:" << content.size() << "\r\n";
@@ -429,10 +357,8 @@ public:
{ {
switch (code) { switch (code) {
case 200: return "OK"; case 200: return "OK";
case 201: return "Created";
case 204: return "no content"; case 204: return "no content";
case 404: return "not found"; case 404: return "not found";
case 407: return "proxy authentication required";
default: return "unknown code"; default: return "unknown code";
} }
} }
@@ -453,8 +379,6 @@ class TestServer : public NetChannel
public: public:
TestServer() TestServer()
{ {
Socket::initSockets();
open(); open();
bind(NULL, 2000); // localhost, any port bind(NULL, 2000); // localhost, any port
listen(5); listen(5);
@@ -490,14 +414,14 @@ TestServer testServer;
void waitForComplete(HTTP::Client* cl, TestRequest* tr) void waitForComplete(HTTP::Client* cl, TestRequest* tr)
{ {
SGTimeStamp start(SGTimeStamp::now()); SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 10000) { while (start.elapsedMSec() < 1000) {
cl->update(); cl->update();
testServer.poll(); testServer.poll();
if (tr->complete) { if (tr->complete) {
return; return;
} }
SGTimeStamp::sleepForMSec(15); SGTimeStamp::sleepForMSec(1);
} }
cerr << "timed out" << endl; cerr << "timed out" << endl;
@@ -506,14 +430,14 @@ void waitForComplete(HTTP::Client* cl, TestRequest* tr)
void waitForFailed(HTTP::Client* cl, TestRequest* tr) void waitForFailed(HTTP::Client* cl, TestRequest* tr)
{ {
SGTimeStamp start(SGTimeStamp::now()); SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 10000) { while (start.elapsedMSec() < 1000) {
cl->update(); cl->update();
testServer.poll(); testServer.poll();
if (tr->failed) { if (tr->failed) {
return; return;
} }
SGTimeStamp::sleepForMSec(15); SGTimeStamp::sleepForMSec(1);
} }
cerr << "timed out waiting for failure" << endl; cerr << "timed out waiting for failure" << endl;
@@ -521,7 +445,6 @@ void waitForFailed(HTTP::Client* cl, TestRequest* tr)
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
sglog().setLogLevels( SG_ALL, SG_INFO );
HTTP::Client cl; HTTP::Client cl;
// force all requests to use the same connection for this test // force all requests to use the same connection for this test
@@ -577,6 +500,8 @@ int main(int argc, char* argv[])
COMPARE(tr->responseCode(), 200); COMPARE(tr->responseCode(), 200);
} }
cerr << "done args" << endl;
{ {
TestRequest* tr = new TestRequest("http://localhost:2000/test_headers"); TestRequest* tr = new TestRequest("http://localhost:2000/test_headers");
HTTP::Request_ptr own(tr); HTTP::Request_ptr own(tr);
@@ -607,7 +532,7 @@ int main(int argc, char* argv[])
COMPARE(tr->bodyData, string(body2, body2Size)); COMPARE(tr->bodyData, string(body2, body2Size));
} }
cerr << "testing chunked transfer encoding" << endl; cerr << "testing chunked" << endl;
{ {
TestRequest* tr = new TestRequest("http://localhost:2000/testchunked"); TestRequest* tr = new TestRequest("http://localhost:2000/testchunked");
HTTP::Request_ptr own(tr); HTTP::Request_ptr own(tr);
@@ -668,40 +593,15 @@ int main(int argc, char* argv[])
} }
cout << "done3" << endl; cout << "done3" << endl;
// test connectToHost failure // test connectToHost failure
/*
{ {
TestRequest* tr = new TestRequest("http://not.found/something"); TestRequest* tr = new TestRequest("http://not.found/something");
HTTP::Request_ptr own(tr); HTTP::Request_ptr own(tr);
cl.makeRequest(tr); cl.makeRequest(tr);
waitForFailed(&cl, tr); waitForFailed(tr);
COMPARE(tr->responseCode(), -1);
#if defined(ENABLE_CURL)
const int HOST_NOT_FOUND_CODE = CURLE_COULDNT_RESOLVE_HOST;
#else
const int HOST_NOT_FOUND_CODE = ENOENT;
#endif
COMPARE(tr->responseCode(), HOST_NOT_FOUND_CODE);
} }
*/
cout << "testing abrupt close" << endl;
// test server-side abrupt close
{
TestRequest* tr = new TestRequest("http://localhost:2000/test_abrupt_close");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForFailed(&cl, tr);
#if defined(ENABLE_CURL)
const int SERVER_NO_DATA_CODE = CURLE_GOT_NOTHING;
#else
const int SERVER_NO_DATA_CODE = 500;
#endif
COMPARE(tr->responseCode(), SERVER_NO_DATA_CODE);
}
cout << "testing proxy close" << endl;
// test proxy // test proxy
{ {
cl.setProxy("localhost", 2000); cl.setProxy("localhost", 2000);
@@ -714,9 +614,8 @@ cout << "testing proxy close" << endl;
COMPARE(tr->bodyData, string(body2, body2Size)); COMPARE(tr->bodyData, string(body2, body2Size));
} }
#if defined(ENABLE_CURL)
{ {
cl.setProxy("localhost", 2000, "johndoe:swordfish"); cl.setProxy("localhost", 2000, "ABCDEF");
TestRequest* tr = new TestRequest("http://www.google.com/test3"); TestRequest* tr = new TestRequest("http://www.google.com/test3");
HTTP::Request_ptr own(tr); HTTP::Request_ptr own(tr);
cl.makeRequest(tr); cl.makeRequest(tr);
@@ -725,10 +624,9 @@ cout << "testing proxy close" << endl;
COMPARE(tr->responseBytesReceived(), body2Size); COMPARE(tr->responseBytesReceived(), body2Size);
COMPARE(tr->bodyData, string(body2, body2Size)); COMPARE(tr->bodyData, string(body2, body2Size));
} }
#endif
// pipelining // pipelining
cout << "testing HTTP 1.1 pipelining" << endl; cout << "testing HTTP 1.1 pipelineing" << endl;
{ {
@@ -791,7 +689,7 @@ cout << "testing proxy close" << endl;
// POST // POST
{ {
cout << "testing POST" << endl; cout << "POST" << endl;
TestRequest* tr = new TestRequest("http://localhost:2000/test_post?foo=abc&bar=1234&username=johndoe", "POST"); TestRequest* tr = new TestRequest("http://localhost:2000/test_post?foo=abc&bar=1234&username=johndoe", "POST");
tr->setBodyData("", "application/x-www-form-urlencoded"); tr->setBodyData("", "application/x-www-form-urlencoded");
@@ -801,29 +699,6 @@ cout << "testing proxy close" << endl;
COMPARE(tr->responseCode(), 204); COMPARE(tr->responseCode(), 204);
} }
// PUT
{
cout << "testing PUT" << endl;
TestRequest* tr = new TestRequest("http://localhost:2000/test_put", "PUT");
tr->setBodyData(BODY3, "x-application/foobar");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 204);
}
{
cout << "testing PUT create" << endl;
TestRequest* tr = new TestRequest("http://localhost:2000/test_create", "PUT");
tr->setBodyData(BODY3, "x-application/foobar");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForComplete(&cl, tr);
COMPARE(tr->responseCode(), 201);
}
// test_zero_length_content // test_zero_length_content
{ {
cout << "zero-length-content-response" << endl; cout << "zero-length-content-response" << endl;
+65 -79
View File
@@ -24,7 +24,7 @@
// Put in some bullet-proofing to handle magnetic and geographic poles. // Put in some bullet-proofing to handle magnetic and geographic poles.
// 3/28/2000 EAW // 3/28/2000 EAW
// //
// Updated coefficient arrays to use the current wmm2005 model, // Updated coefficient arrays to use the current WMM2005 model,
// (valid between 2005.0 and 2010.0) // (valid between 2005.0 and 2010.0)
// Also removed unused variables and corrected earth radii constants // Also removed unused variables and corrected earth radii constants
// to the values for WGS84 and WMM2005. // to the values for WGS84 and WMM2005.
@@ -36,20 +36,6 @@
// //
// 25/10/2006 Wim Van Hoydonck -- wim.van.hoydonck@gmail.com // 25/10/2006 Wim Van Hoydonck -- wim.van.hoydonck@gmail.com
// //
//
// Updated coefficient arrays to use the current WMM2015 model,
// (valid between 2015.0 and 2020.0)
// Also removed unused variables and corrected earth radii constants
// to the values for WGS84 and WMM2015.
// Reference:
// A. Chulliat , S. Macmillan, P. Alken, C. Beggan, M.
// Nair, B. Hamilton, A. Woods, V. Ridley,
// S Maus, and A Thomson, December 2014, The
// US/UK World Magnetic Model for 2015-2020,
// NOAA Technical Report WMM2015_Report.pdf
//
// 18/06/2015 Jean-Paul Anceaux -- j.p.r.anceaux@gmail.com
// The routine uses a spherical harmonic expansion of the magnetic // The routine uses a spherical harmonic expansion of the magnetic
// potential up to twelfth order, together with its time variation, as // potential up to twelfth order, together with its time variation, as
@@ -93,7 +79,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <cmath> #include <math.h>
#include <simgear/constants.h> #include <simgear/constants.h>
#include <simgear/sg_inlines.h> #include <simgear/sg_inlines.h>
@@ -104,72 +90,72 @@ static const double a = 6378.137; /* semi-major axis (equatorial radius) o
static const double b = 6356.7523142; /* semi-minor axis referenced to the WGS84 ellipsoid */ static const double b = 6356.7523142; /* semi-minor axis referenced to the WGS84 ellipsoid */
static const double r_0 = 6371.2; /* standard Earth magnetic reference radius */ static const double r_0 = 6371.2; /* standard Earth magnetic reference radius */
static double gnm_wmm2015[13][13] = static double gnm_wmm2005[13][13] =
{ {
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-29438.5, -1501.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-29556.8, -1671.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-2445.3, 3012.5, 1676.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-2340.6, 3046.9, 1657.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{1351.1, -2352.3, 1225.6, 581.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {1335.4, -2305.1, 1246.7, 674.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{907.2, 813.7, 120.3, -335.0, 70.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {919.8, 798.1, 211.3, -379.4, 100.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-232.6, 360.1, 192.4, -141.0, -157.4, 4.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-227.4, 354.6, 208.7, -136.5, -168.3, -14.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{69.5, 67.4, 72.8, -129.8, -29.0, 13.2, -70.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {73.2, 69.7, 76.7, -151.2, -14.9, 14.6, -86.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{81.6, -76.1, -6.8, 51.9, 15.0, 9.3, -2.8, 6.7, 0.0, 0.0, 0.0, 0.0, 0.0}, {80.1, -74.5, -1.4, 38.5, 12.4, 9.5, 5.7, 1.8, 0.0, 0.0, 0.0, 0.0, 0.0},
{24.0, 8.6, -16.9, -3.2, -20.6, 13.3, 11.7, -16.0, -2.0, 0.0, 0.0, 0.0, 0.0}, {24.9, 7.7, -11.6, -6.9, -18.2, 10.0, 9.2, -11.6, -5.2, 0.0, 0.0, 0.0, 0.0},
{5.4, 8.8, 3.1, -3.1, 0.6, -13.3, -0.1, 8.7, -9.1, -10.5, 0.0, 0.0, 0.0}, {5.6, 9.9, 3.5, -7.0, 5.1, -10.8, -1.3, 8.8, -6.7, -9.1, 0.0, 0.0, 0.0},
{-1.9, -6.5, 0.2, 0.6, -0.6, 1.7, -0.7, 2.1, 2.3, -1.8, -3.6, 0.0, 0.0}, {-2.3, -6.3, 1.6, -2.6, 0.0, 3.1, 0.4, 2.1, 3.9, -0.1, -2.3, 0.0, 0.0},
{3.1, -1.5, -2.3, 2.1, -0.9, 0.6, -0.7, 0.2, 1.7, -0.2, 0.4, 3.5, 0.0}, {2.8, -1.6, -1.7, 1.7, -0.1, 0.1, -0.7, 0.7, 1.8, 0.0, 1.1, 4.1, 0.0},
{-2.0, -0.3, 0.4, 1.3, -0.9, 0.9, 0.1, 0.5, -0.4, -0.4, 0.2, -0.9, 0.0}, {-2.4, -0.4, 0.2, 0.8, -0.3, 1.1, -0.5, 0.4, -0.3, -0.3, -0.1, -0.3, -0.1},
}; };
static double hnm_wmm2015[13][13]= static double hnm_wmm2005[13][13]=
{ {
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 4796.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 5079.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -2845.6, -642.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -2594.7, -516.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -115.3, 245.0, -538.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -199.9, 269.3, -524.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 283.4, -188.6, 180.9, -329.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 281.5, -226.0, 145.8, -304.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 47.4, 196.9, -119.4, 16.1, 100.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 42.4, 179.8, -123.0, -19.5, 103.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -20.7, 33.2, 58.8, -66.5, 7.3, 62.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -20.3, 54.7, 63.6, -63.4, -0.1, 50.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -54.1, -19.4, 5.6, 24.4, 3.3, -27.5, -2.3, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -61.5, -22.4, 7.2, 25.4, 11.0, -26.4, -5.1, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 10.2, -18.1, 13.2, -14.6, 16.2, 5.7, -9.1, 2.2, 0.0, 0.0, 0.0, 0.0}, {0.0, 11.2, -21.0, 9.6, -19.8, 16.1, 7.7, -12.9, -0.2, 0.0, 0.0, 0.0, 0.0},
{0.0, -21.6, 10.8, 11.7, -6.8, -6.9, 7.8, 1.0, -3.9, 8.5, 0.0, 0.0, 0.0}, {0.0, -20.1, 12.9, 12.6, -6.7, -8.1, 8.0, 2.9, -7.9, 6.0, 0.0, 0.0, 0.0},
{0.0, 3.3, -0.3, 4.6, 4.4, -7.9, -0.6, -4.1, -2.8, -1.1, -8.7, 0.0, 0.0}, {0.0, 2.4, 0.2, 4.4, 4.8, -6.5, -1.1, -3.4, -0.8, -2.3, -7.9, 0.0, 0.0},
{0.0, -0.1, 2.1, -0.7, -1.1, 0.7, -0.2, -2.1, -1.5, -2.5, -2.0, -2.3, 0.0}, {0.0, 0.3, 1.2, -0.8, -2.5, 0.9, -0.6, -2.7, -0.9, -1.3, -2.0, -1.2, 0.0},
{0.0, -1.0, 0.5, 1.8, -2.2, 0.3, 0.7, -0.1, 0.3, 0.2, -0.9, -0.2, 0.7}, {0.0, -0.4, 0.3, 2.4, -2.6, 0.6, 0.3, 0.0, 0.0, 0.3, -0.9, -0.4, 0.8},
}; };
static double gtnm_wmm2015[13][13]= static double gtnm_wmm2005[13][13]=
{ {
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{10.7, 17.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {8.0, 10.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-8.6, -3.3, 2.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-15.1, -7.8, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{3.1, -6.2, -0.4, -10.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.4, -2.6, -1.2, -6.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.4, 0.8, -9.2, 4.0, -4.2, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-2.5, 2.8, -7.0, 6.2, -3.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.2, 0.1, -1.4, 0.0, 1.3, 3.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-2.8, 0.7, -3.2, -1.1, 0.1, -0.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{-0.5, -0.2, -0.6, 2.4, -1.1, 0.3, 1.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {-0.7, 0.4, -0.3, 2.3, -2.1, -0.6, 1.4, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.2, -0.2, -0.4, 1.3, 0.2, -0.4, -0.9, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.2, -0.1, -0.3, 1.1, 0.6, 0.5, -0.4, 0.6, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.1, -0.5, 0.5, -0.2, 0.4, 0.2, -0.4, 0.3, 0.0, 0.0, 0.0, 0.0}, {0.1, 0.3, -0.4, 0.3, -0.3, 0.2, 0.4, -0.7, 0.4, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.1, -0.1, 0.4, -0.5, -0.2, 0.1, 0.0, -0.2, -0.1, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, -0.1, 0.3, -0.1, -0.1, -0.1, 0.0, -0.2, -0.1, -0.2, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, -0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1, -0.1, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.1, 0.0, 0.0, 0.1, -0.1, 0.0, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
}; };
static double htnm_wmm2015[13][13]= static double htnm_wmm2005[13][13]=
{ {
{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -26.8, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -20.9, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -27.1, -13.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -23.2, -14.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 8.4, -0.4, 2.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 5.0, -7.0, -0.6, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.6, 5.3, 3.0, -5.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 2.2, 1.6, 5.8, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.4, 1.6, -1.1, 3.3, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 1.7, 2.1, 4.8, -1.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, -2.2, -0.7, 0.1, 1.0, 1.3, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -0.6, -1.9, -0.4, -0.5, -0.3, 0.7, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.7, 0.5, -0.2, -0.1, -0.7, 0.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.6, 0.4, 0.2, 0.3, -0.8, -0.2, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.3, 0.3, 0.3, 0.6, -0.1, -0.2, 0.3, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, -0.2, 0.1, 0.3, 0.4, 0.1, -0.2, 0.4, 0.4, 0.0, 0.0, 0.0, 0.0},
{0.0, -0.2, -0.1, -0.2, 0.1, 0.1, 0.0, -0.2, 0.4, 0.3, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.1, -0.1, 0.0, 0.0, -0.2, 0.1, -0.1, -0.2, 0.1, -0.1, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.1, 0.0, 0.1, 0.0, 0.0, 0.1, 0.0, -0.1, 0.0, -0.1, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 0.0, -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0}, {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
}; };
static const int nmax = 12; static const int nmax = 12;
@@ -209,8 +195,8 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
{ {
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */ /* output field B_r,B_th,B_phi,B_x,B_y,B_z */
int n,m; int n,m;
/* reference date for current model is 1 januari 2015 */ /* reference date for current model is 1 januari 2005 */
long date0_wmm2015 = yymmdd_to_julian_days(15,1,1); long date0_wmm2005 = yymmdd_to_julian_days(5,1,1);
double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z; double yearfrac,sr,r,theta,c,s,psi,fn,fn_0,B_r,B_theta,B_phi,X,Y,Z;
double sinpsi, cospsi, inv_s; double sinpsi, cospsi, inv_s;
@@ -297,12 +283,12 @@ double calc_magvar( double lat, double lon, double h, long dat, double* field )
/* compute Gauss coefficients gnm and hnm of degree n and order m for the desired time /* compute Gauss coefficients gnm and hnm of degree n and order m for the desired time
achieved by adjusting the coefficients at time t0 for linear secular variation */ achieved by adjusting the coefficients at time t0 for linear secular variation */
/* WMM2015 */ /* WMM2005 */
yearfrac = (dat - date0_wmm2015) / 365.25; yearfrac = (dat - date0_wmm2005) / 365.25;
for ( n = 1; n <= nmax; n++ ) { for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) { for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2015[n][m] + yearfrac * gtnm_wmm2015[n][m]; gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[n][m];
hnm[n][m] = hnm_wmm2015[n][m] + yearfrac * htnm_wmm2015[n][m]; hnm[n][m] = hnm_wmm2005[n][m] + yearfrac * htnm_wmm2005[n][m];
} }
} }
@@ -364,7 +350,7 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
/* output field B_r,B_th,B_phi,B_x,B_y,B_z */ /* output field B_r,B_th,B_phi,B_x,B_y,B_z */
int n,m; int n,m;
/* reference dates */ /* reference dates */
long date0_wmm2015 = yymmdd_to_julian_days(5,1,1); long date0_wmm2005 = yymmdd_to_julian_days(5,1,1);
double yearfrac,sr,r,theta,c,s,psi,fn,B_r,B_theta,B_phi,X,Y,Z; double yearfrac,sr,r,theta,c,s,psi,fn,B_r,B_theta,B_phi,X,Y,Z;
@@ -421,12 +407,12 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
} }
/* compute gnm, hnm at dat */ /* compute gnm, hnm at dat */
/* WMM2015 */ /* WMM2005 */
yearfrac = (dat - date0_wmm2015) / 365.25; yearfrac = (dat - date0_wmm2005) / 365.25;
for ( n = 1; n <= nmax; n++ ) { for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) { for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2015[n][m] + yearfrac * gtnm_wmm2015[n][m]; gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[n][m];
hnm[n][m] = hnm_wmm2015[n][m] + yearfrac * htnm_wmm2015[n][m]; hnm[n][m] = hnm_wmm2005[n][m] + yearfrac * htnm_wmm2005[n][m];
} }
} }
+1 -1
View File
@@ -26,7 +26,7 @@
#endif #endif
#include <cmath> #include <math.h>
#include <simgear/magvar/magvar.hxx> #include <simgear/magvar/magvar.hxx>
#include <simgear/math/SGMath.hxx> #include <simgear/math/SGMath.hxx>
+1 -1
View File
@@ -2,7 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <cmath> #include <math.h>
#include <simgear/constants.h> #include <simgear/constants.h>
+1 -1
View File
@@ -154,7 +154,7 @@ public:
static bool isNaN(const T& v) static bool isNaN(const T& v)
{ {
#ifdef HAVE_ISNAN #ifdef HAVE_ISNAN
return (isnan(v) != 0); return isnan(v);
#elif defined HAVE_STD_ISNAN #elif defined HAVE_STD_ISNAN
return std::isnan(v); return std::isnan(v);
#else #else
+1 -1
View File
@@ -59,7 +59,7 @@ namespace simgear
} }
void setMaxSubdiv( size_t aMaxSubdiv ) { mMaxSubdiv = aMaxSubdiv; } void setMaxSubdiv( size_t aMaxSubdiv ) { mMaxSubdiv = aMaxSubdiv; }
size_t getMaxSubdiv() const { return mMaxSubdiv; } void getMaxSubdiv() const { return mMaxSubdiv; }
PointList &pointList() { return mPointList; } PointList &pointList() { return mPointList; }
const PointList &pointList() const { return mPointList; } const PointList &pointList() const { return mPointList; }
+1 -1
View File
@@ -67,7 +67,7 @@ SGInterpTable::SGInterpTable( const std::string& file )
while ( in ) { while ( in ) {
double ind, dep; double ind, dep;
in >> ind >> dep; in >> ind >> dep;
in >> std::skipws; in >> skipws;
_table[ind] = dep; _table[ind] = dep;
} }
} }
-4
View File
@@ -37,10 +37,6 @@ set(SOURCES
gzcontainerfile.cxx gzcontainerfile.cxx
) )
if (WINDOWS)
list(APPEND HEADERS sgversionhelpers.hxx)
endif()
if (APPLE) if (APPLE)
list(APPEND SOURCES CocoaHelpers.mm) list(APPEND SOURCES CocoaHelpers.mm)
endif() endif()
-4
View File
@@ -141,11 +141,7 @@ int main(int argc, char* argv[])
// add // add
pc.add("/opt/local"); pc.add("/opt/local");
#ifdef _WIN32
COMPARE(pc.str(), std::string("/usr/local/include/;/opt/local"));
#else
COMPARE(pc.str(), std::string("/usr/local/include/:/opt/local")); COMPARE(pc.str(), std::string("/usr/local/include/:/opt/local"));
#endif
// concat // concat
SGPath pd = pb; SGPath pd = pb;
-1
View File
@@ -382,7 +382,6 @@ bool Dir::remove(bool recursive)
if (recursive) { if (recursive) {
if (!removeChildren()) { if (!removeChildren()) {
SG_LOG(SG_IO, SG_WARN, "Dir at:" << _path << " failed to remove children");
return false; return false;
} }
} // of recursive deletion } // of recursive deletion
+25 -88
View File
@@ -57,9 +57,6 @@ static const char sgSearchPathSep = ':';
#ifdef _WIN32 #ifdef _WIN32
#include <ShlObj.h> // for CSIDL #include <ShlObj.h> // for CSIDL
// TODO: replace this include file with the official <versionhelpers.h> header
// included in the Windows 8.1 SDK
#include "sgversionhelpers.hxx"
static SGPath pathForCSIDL(int csidl, const SGPath& def) static SGPath pathForCSIDL(int csidl, const SGPath& def)
{ {
@@ -83,42 +80,6 @@ static SGPath pathForCSIDL(int csidl, const SGPath& def)
return def; return def;
} }
static SGPath pathForKnownFolder(REFKNOWNFOLDERID folderId, const SGPath& def)
{
typedef HRESULT (WINAPI*PSHGKFP)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR*);
HINSTANCE shellDll = LoadLibrary(TEXT("shell32"));
if (shellDll != NULL) {
PSHGKFP pSHGetKnownFolderPath = (PSHGKFP) GetProcAddress(shellDll, "SHGetKnownFolderPath");
if (pSHGetKnownFolderPath != NULL) {
// system call will allocate dynamic memory... which we must release when done
wchar_t* localFolder = 0;
if (pSHGetKnownFolderPath(folderId, KF_FLAG_DEFAULT_PATH, NULL, &localFolder) == S_OK) {
// copy into local memory
char path[MAX_PATH];
size_t len;
if (wcstombs_s(&len, path, localFolder, MAX_PATH) != S_OK) {
path[0] = '\0';
SG_LOG(SG_GENERAL, SG_WARN, "WCS to MBS failed");
}
SGPath folder_path = SGPath(path, def.getPermissionChecker());
// release dynamic memory
CoTaskMemFree(static_cast<void*>(localFolder));
return folder_path;
}
}
FreeLibrary(shellDll);
}
return def;
}
#elif __APPLE__ #elif __APPLE__
// defined in CocoaHelpers.mm // defined in CocoaHelpers.mm
@@ -743,35 +704,20 @@ SGPath SGPath::standardLocation(StandardLocation type, const SGPath& def)
{ {
case HOME: case HOME:
return home(def); return home(def);
#ifdef _WIN32 #ifdef _WIN32
case DESKTOP: case DESKTOP:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Desktop, def);
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def); return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
case DOWNLOADS: case DOWNLOADS:
if (IsWindowsVistaOrGreater()) // TODO use KnownFolders
return pathForKnownFolder(FOLDERID_Downloads, def); // http://msdn.microsoft.com/en-us/library/bb776911%28v=vs.85%29.aspx
if( !def.isNull() )
if (!def.isNull())
return def; return def;
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def); return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
case DOCUMENTS: case DOCUMENTS:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Documents, def);
return pathForCSIDL(CSIDL_MYDOCUMENTS, def); return pathForCSIDL(CSIDL_MYDOCUMENTS, def);
case PICTURES: case PICTURES:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Pictures, def);
return pathForCSIDL(CSIDL_MYPICTURES, def); return pathForCSIDL(CSIDL_MYPICTURES, def);
#elif __APPLE__ #elif __APPLE__
// since this is C++, we can't include NSPathUtilities.h to access the enum // since this is C++, we can't include NSPathUtilities.h to access the enum
// values, so hard-coding them here (they are stable, don't worry) // values, so hard-coding them here (they are stable, don't worry)
@@ -810,15 +756,20 @@ SGPath SGPath::fromEnv(const char* name, const SGPath& def)
return def; return def;
} }
#ifdef _WIN32
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
SGPath SGPath::home(const SGPath& def) SGPath SGPath::home(const SGPath& def)
{ {
#ifdef _WIN32 // TODO
return fromEnv("USERPROFILE", def); return def;
#else
return fromEnv("HOME", def);
#endif
} }
#else
//------------------------------------------------------------------------------
SGPath SGPath::home(const SGPath& def)
{
return fromEnv("HOME", def);
}
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
SGPath SGPath::desktop(const SGPath& def) SGPath SGPath::desktop(const SGPath& def)
@@ -835,39 +786,25 @@ SGPath SGPath::documents(const SGPath& def)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::string SGPath::realpath() const std::string SGPath::realpath() const
{ {
#if defined(_MSC_VER) /*for MS compilers */ || defined(_WIN32) /*needed for non MS windows compilers like MingW*/ #if (defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1050)
// Workaround for Mac OS 10.5. Somehow fgfs crashes on Mac at ::realpath.
// This means relative paths cannot be used on Mac OS <= 10.5
return path;
#else
#if defined(_MSC_VER) /*for MS compilers */ || defined(_WIN32) /*needed for non MS windows compilers like MingW*/
// with absPath NULL, will allocate, and ignore length // with absPath NULL, will allocate, and ignore length
char *buf = _fullpath( NULL, path.c_str(), _MAX_PATH ); char *buf = _fullpath( NULL, path.c_str(), _MAX_PATH );
#else #else
// POSIX // POSIX
char* buf = ::realpath(path.c_str(), NULL); char* buf = ::realpath(path.c_str(), NULL);
#endif #endif
if (!buf) // File does not exist: return the realpath it would have if created now if (!buf)
// (needed for fgValidatePath security)
{ {
if (path.empty()) { SG_LOG(SG_IO, SG_ALERT, "ERROR: The path '" << path << "' does not exist in the file system.");
return SGPath(".").realpath(); // current directory return path;
}
std::string this_dir = dir();
if (isAbsolute() && this_dir.empty()) { // top level
this_dir = "/";
}
if (file() == "..") {
this_dir = SGPath(SGPath(this_dir).realpath()).dir();
if (this_dir.empty()) { // invalid path: .. above root
return "";
}
return SGPath(this_dir).realpath(); // use native path separator,
// and handle 'existing/nonexisting/../symlink' paths
}
return SGPath(this_dir).realpath() +
#if defined(_MSC_VER) || defined(_WIN32)
"\\" + file();
#else
"/" + file();
#endif
} }
std::string p(buf); std::string p(buf);
free(buf); free(buf);
return p; return p;
#endif
} }
-122
View File
@@ -1,122 +0,0 @@
// Clean drop-in replacement for the versionhelpers.h header
//
// Copyright (C) 2015 Alessandro Menti <alessandro.menti@hotmail.it>
//
// 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
#ifndef SG_VERSIONHELPERS_HXX_
#define SG_VERSIONHELPERS_HXX_
#include <sdkddkver.h>
#ifdef __cplusplus
#define VERSIONHELPERAPI inline bool
#else
#define VERSIONHELPERAPI FORCEINLINE BOOL
#endif // __cplusplus
/* Windows 8/8.1 version numbers, not defined in the Windows 7 SDK. */
#ifndef _WIN32_WINNT_WIN8
#define _WIN32_WINNT_WIN8 0x0602
#endif
#ifndef _WIN32_WINNT_WINBLUE
#define _WIN32_WINNT_WINBLUE 0x0603
#endif
VERSIONHELPERAPI IsWindowsVersionOrGreater(WORD wMajorVersion,
WORD wMinorVersion, WORD wServicePackMajor) {
OSVERSIONINFOEXW osVersionInfo;
DWORDLONG dwlConditionMask = 0;
ZeroMemory(&osVersionInfo, sizeof(osVersionInfo));
osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);
osVersionInfo.dwMajorVersion = wMajorVersion;
osVersionInfo.dwMinorVersion = wMinorVersion;
osVersionInfo.wServicePackMajor = wServicePackMajor;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION,
VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION,
VER_GREATER_EQUAL);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR,
VER_GREATER_EQUAL);
return VerifyVersionInfoW(&osVersionInfo, VER_MAJORVERSION
| VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask);
}
VERSIONHELPERAPI IsWindowsXPOrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP),
LOBYTE(_WIN32_WINNT_WINXP), 0);
}
VERSIONHELPERAPI IsWindowsXPSP1OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP),
LOBYTE(_WIN32_WINNT_WINXP), 1);
}
VERSIONHELPERAPI IsWindowsXPSP2OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP),
LOBYTE(_WIN32_WINNT_WINXP), 2);
}
VERSIONHELPERAPI IsWindowsXPSP3OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINXP),
LOBYTE(_WIN32_WINNT_WINXP), 3);
}
VERSIONHELPERAPI IsWindowsVistaOrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA),
LOBYTE(_WIN32_WINNT_VISTA), 0);
}
VERSIONHELPERAPI IsWindowsVistaSP1OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA),
LOBYTE(_WIN32_WINNT_VISTA), 1);
}
VERSIONHELPERAPI IsWindowsVistaSP2OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_VISTA),
LOBYTE(_WIN32_WINNT_VISTA), 2);
}
VERSIONHELPERAPI IsWindows7OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7),
LOBYTE(_WIN32_WINNT_WIN7), 0);
}
VERSIONHELPERAPI IsWindows7SP1OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN7),
LOBYTE(_WIN32_WINNT_WIN7), 1);
}
VERSIONHELPERAPI IsWindows8OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WIN8),
LOBYTE(_WIN32_WINNT_WIN8), 0);
}
VERSIONHELPERAPI IsWindows8Point1OrGreater() {
return IsWindowsVersionOrGreater(HIBYTE(_WIN32_WINNT_WINBLUE),
LOBYTE(_WIN32_WINNT_WINBLUE), 0);
}
VERSIONHELPERAPI IsWindowsServer() {
OSVERSIONINFOEXW osVersionInfo;
DWORDLONG dwlConditionMask = 0;
ZeroMemory(&osVersionInfo, sizeof(osVersionInfo));
osVersionInfo.dwOSVersionInfoSize = sizeof(osVersionInfo);
osVersionInfo.wProductType = VER_NT_WORKSTATION;
VER_SET_CONDITION(dwlConditionMask, VER_PRODUCT_TYPE, VER_EQUAL);
return !VerifyVersionInfoW(&osVersionInfo, VER_PRODUCT_TYPE,
dwlConditionMask);
}
#endif // SG_VERSIONHELPERS_HXX_
-1
View File
@@ -23,7 +23,6 @@
#include <ctype.h> #include <ctype.h>
#include <cstring> #include <cstring>
#include <sstream> #include <sstream>
#include <algorithm>
#include "strutils.hxx" #include "strutils.hxx"
+1 -1
View File
@@ -4,7 +4,6 @@ include (SimGearComponent)
set(HEADERS set(HEADERS
naref.h naref.h
nasal.h nasal.h
iolib.h
) )
set(SOURCES set(SOURCES
@@ -27,6 +26,7 @@ set(SOURCES
vector.c vector.c
code.h code.h
data.h data.h
iolib.h
parse.h parse.h
) )
+8
View File
@@ -66,6 +66,14 @@ namespace nasal
void GhostMetadata::addDerived(const GhostMetadata* derived) void GhostMetadata::addDerived(const GhostMetadata* derived)
{ {
assert(derived); assert(derived);
SG_LOG
(
SG_NASAL,
SG_INFO,
"Ghost::addDerived: " << _name_strong << " -> "
<< derived->_name_strong
);
} }
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -39,12 +39,6 @@ static void runNumTests( double (TestContext::*test_double)(const std::string&),
BOOST_CHECK_EQUAL((c.*test_int)("0x755"), 0x755); BOOST_CHECK_EQUAL((c.*test_int)("0x755"), 0x755);
BOOST_CHECK_EQUAL((c.*test_int)("0x055"), 0x55); BOOST_CHECK_EQUAL((c.*test_int)("0x055"), 0x55);
BOOST_CHECK_EQUAL((c.*test_int)("-0x155"), -0x155); BOOST_CHECK_EQUAL((c.*test_int)("-0x155"), -0x155);
BOOST_CHECK_CLOSE((c.*test_double)("2.000000953656983160"),
2.000000953656983160, 1e-5);
/* this value has bit pattern 0x400000007fff6789L,
* so will look like a pointer if the endianness is set wrong
* (see naref.h, data.h)*/
} }
BOOST_AUTO_TEST_CASE( parse_num ) BOOST_AUTO_TEST_CASE( parse_num )
-6
View File
@@ -142,9 +142,6 @@ naRef naIOGhost(naContext c, FILE* f)
return naNewGhost(c, &naIOGhostType, ghost); return naNewGhost(c, &naIOGhostType, ghost);
} }
#if SG_NASAL_UNRESTRICTED_OPEN
// Allows unrestricted file access, which would be a security hole
// Replaced by the one in flightgear src/Scripting/NasalSys.cxx
static naRef f_open(naContext c, naRef me, int argc, naRef* args) static naRef f_open(naContext c, naRef me, int argc, naRef* args)
{ {
FILE* f; FILE* f;
@@ -155,7 +152,6 @@ static naRef f_open(naContext c, naRef me, int argc, naRef* args)
if(!f) naRuntimeError(c, strerror(errno)); if(!f) naRuntimeError(c, strerror(errno));
return naIOGhost(c, f); return naIOGhost(c, f);
} }
#endif
// frees buffer before tossing an error // frees buffer before tossing an error
static int getcguard(naContext ctx, FILE* f, void* buf) static int getcguard(naContext ctx, FILE* f, void* buf)
@@ -248,9 +244,7 @@ static naCFuncItem funcs[] = {
{ "seek", f_seek }, { "seek", f_seek },
{ "tell", f_tell }, { "tell", f_tell },
{ "flush", f_flush }, { "flush", f_flush },
#if SG_NASAL_UNRESTRICTED_OPEN
{ "open", f_open }, { "open", f_open },
#endif
{ "readln", f_readln }, { "readln", f_readln },
{ "stat", f_stat }, { "stat", f_stat },
{ 0 } { 0 }
+1 -6
View File
@@ -1,8 +1,5 @@
#ifndef _IOLIB_H #ifndef _IOLIB_H
#define _IOLIB_H #define _IOLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#include "nasal.h" #include "nasal.h"
@@ -36,7 +33,5 @@ extern struct naIOType naStdIOType;
// Defined in iolib.c, there is no "library" header to put this in // Defined in iolib.c, there is no "library" header to put this in
naRef naIOGhost(naContext c, FILE* f); naRef naIOGhost(naContext c, FILE* f);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _IOLIB_H #endif // _IOLIB_H
+15 -18
View File
@@ -1,31 +1,28 @@
#ifndef _NAREF_H #ifndef _NAREF_H
#define _NAREF_H #define _NAREF_H
/* Rather than play elaborate and complicated games with
* platform-dependent endianness headers, just detect the platforms we
* support. This list is simpler and smaller, yet still quite
* complete. */
#if (defined(__x86_64) && defined(__linux__)) || defined(__sparcv9) || \ #if (defined(__x86_64) && defined(__linux__)) || defined(__sparcv9) || \
defined(__powerpc64__) defined(__powerpc64__)
/* NASAL_NAN64 mode requires 64 bit pointers that only use the /* Win64 and Irix should work with this too, but have not been
* lower 48 bits; Win64 and Irix should work with this too, but * tested */
* have not been tested */
# define NASAL_NAN64 # define NASAL_NAN64
#elif defined(__BYTE_ORDER__) #elif defined(_M_IX86) || defined(i386) || defined(__x86_64) || \
/* GCC and Clang define these (as a builtin, while
* __LITTLE_ENDIAN__ requires a header), MSVC doesn't */
# if __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
# define NASAL_LE
# elif __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
# define NASAL_BE
# else
# error Unrecognized endianness
# endif
#elif defined(_M_IX86) || defined(__i386) || defined(__x86_64) || \
defined(__ia64__) || defined(_M_IA64) || defined(__ARMEL__) || \ defined(__ia64__) || defined(_M_IA64) || defined(__ARMEL__) || \
defined(_M_X64) || defined(_M_ARM) defined(_M_X64) || defined(__alpha__) || \
(defined(__sh__) && defined(__LITTLE_ENDIAN__))
# define NASAL_LE # define NASAL_LE
#elif defined(__sparc) || defined(__ARMEB__) || \ #elif defined(__sparc) || defined(__ppc__) || defined(__PPC) || \
defined(__hppa__) || defined(__s390__) || defined(__s390x__) defined (__powerpc__) || defined (__powerpc64__) || defined (__alpha__) || \
defined(__mips) || defined(__ARMEB__) || \
defined(__hppa__) || defined(__s390__) || defined(__s390x__) || \
(defined(__sh__) && !defined(__LITTLE_ENDIAN__))
# define NASAL_BE # define NASAL_BE
#else #else
# error Unknown endianness # error Unrecognized CPU architecture
#endif #endif
typedef union { typedef union {
-12
View File
@@ -26,15 +26,3 @@ if(ENABLE_PKGUTIL)
add_executable(sg_pkgutil pkgutil.cxx) add_executable(sg_pkgutil pkgutil.cxx)
target_link_libraries(sg_pkgutil ${TEST_LIBS}) target_link_libraries(sg_pkgutil ${TEST_LIBS})
endif() endif()
if(ENABLE_TESTS)
add_executable(catalog_test CatalogTest.cxx)
target_link_libraries(catalog_test ${TEST_LIBS})
set_target_properties(catalog_test PROPERTIES
COMPILE_DEFINITIONS "SRC_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"" )
add_test(catalog_test ${EXECUTABLE_OUTPUT_PATH}/catalog_test)
endif(ENABLE_TESTS)
+60 -189
View File
@@ -31,56 +31,12 @@
#include <simgear/package/Package.hxx> #include <simgear/package/Package.hxx>
#include <simgear/package/Root.hxx> #include <simgear/package/Root.hxx>
#include <simgear/package/Install.hxx> #include <simgear/package/Install.hxx>
#include <simgear/misc/strutils.hxx>
namespace simgear { namespace simgear {
namespace pkg { namespace pkg {
bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props) CatalogList static_catalogs;
{
BOOST_FOREACH(SGPropertyNode* v, props->getChildren("version")) {
std::string s(v->getStringValue());
if (s == aVersion) {
return true;
}
// examine each dot-seperated component in turn, supporting a wildcard
// in the versions from the catalog.
string_list appVersionParts = simgear::strutils::split(aVersion, ".");
string_list catVersionParts = simgear::strutils::split(s, ".");
size_t partCount = appVersionParts.size();
if (partCount != catVersionParts.size()) {
continue;
}
bool ok = true;
for (unsigned int p=0; p < partCount; ++p) {
if (catVersionParts[p] == "*") {
// always passes
} else if (appVersionParts[p] != catVersionParts[p]) {
ok = false;
}
}
if (ok) {
return true;
}
}
return false;
}
std::string redirectUrlForVersion(const std::string& aVersion, SGPropertyNode_ptr props)
{
BOOST_FOREACH(SGPropertyNode* v, props->getChildren("alternate-version")) {
if (v->getStringValue("version") == aVersion) {
return v->getStringValue("url");
}
}
return std::string();
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@@ -91,8 +47,6 @@ public:
HTTP::Request(aUrl), HTTP::Request(aUrl),
m_owner(aOwner) m_owner(aOwner)
{ {
// refreshing
m_owner->changeStatus(Delegate::STATUS_IN_PROGRESS);
} }
protected: protected:
@@ -104,13 +58,8 @@ protected:
virtual void onDone() virtual void onDone()
{ {
if (responseCode() != 200) { if (responseCode() != 200) {
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD; SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url());
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url() m_owner->refreshComplete(Delegate::FAIL_DOWNLOAD);
<< "\n\t" << responseCode());
if (responseCode() == 404) {
code = Delegate::FAIL_NOT_FOUND;
}
m_owner->refreshComplete(code);
return; return;
} }
@@ -125,35 +74,13 @@ protected:
return; return;
} }
if (m_owner->root()->catalogVersion() != props->getIntValue("catalog-version")) { std::string ver(m_owner->root()->catalogVersion());
SG_LOG(SG_GENERAL, SG_WARN, "catalog:" << m_owner->url() << " is not version "
<< m_owner->root()->catalogVersion());
m_owner->refreshComplete(Delegate::FAIL_VERSION);
return;
}
std::string ver(m_owner->root()->applicationVersion());
if (!checkVersion(ver, props)) { if (!checkVersion(ver, props)) {
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t" SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t"
<< props->getStringValue("version") << " vs required " << ver); << props->getStringValue("version") << " vs required " << ver);
// check for a version redirect entry
std::string url = redirectUrlForVersion(ver, props);
if (!url.empty()) {
SG_LOG(SG_GENERAL, SG_WARN, "redirecting from " << m_owner->url() <<
" to \n\t" << url);
// update the URL and kick off a new request
m_owner->m_url = url;
Downloader* dl = new Downloader(m_owner, url);
m_owner->root()->makeHTTPRequest(dl);
} else {
m_owner->refreshComplete(Delegate::FAIL_VERSION); m_owner->refreshComplete(Delegate::FAIL_VERSION);
}
return; return;
} // of version check failed }
// cache the catalog data, now we have a valid install root // cache the catalog data, now we have a valid install root
Dir d(m_owner->installRoot()); Dir d(m_owner->installRoot());
@@ -165,10 +92,19 @@ protected:
time(&m_owner->m_retrievedTime); time(&m_owner->m_retrievedTime);
m_owner->writeTimestamp(); m_owner->writeTimestamp();
m_owner->refreshComplete(Delegate::STATUS_REFRESHED); m_owner->refreshComplete(Delegate::FAIL_SUCCESS);
} }
private: private:
bool checkVersion(const std::string& aVersion, SGPropertyNode* aProps)
{
BOOST_FOREACH(SGPropertyNode* v, aProps->getChildren("version")) {
if (v->getStringValue() == aVersion) {
return true;
}
}
return false;
}
CatalogRef m_owner; CatalogRef m_owner;
std::string m_buffer; std::string m_buffer;
@@ -176,22 +112,31 @@ private:
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
CatalogList Catalog::allCatalogs()
{
return static_catalogs;
}
Catalog::Catalog(Root *aRoot) : Catalog::Catalog(Root *aRoot) :
m_root(aRoot), m_root(aRoot),
m_status(Delegate::FAIL_UNKNOWN),
m_retrievedTime(0) m_retrievedTime(0)
{ {
static_catalogs.push_back(this);
} }
Catalog::~Catalog() Catalog::~Catalog()
{ {
CatalogList::iterator it = std::find(static_catalogs.begin(), static_catalogs.end(), this);
static_catalogs.erase(it);
} }
CatalogRef Catalog::createFromUrl(Root* aRoot, const std::string& aUrl) CatalogRef Catalog::createFromUrl(Root* aRoot, const std::string& aUrl)
{ {
CatalogRef c = new Catalog(aRoot); CatalogRef c = new Catalog(aRoot);
c->m_url = aUrl; c->m_url = aUrl;
c->refresh(); Downloader* dl = new Downloader(c, aUrl);
aRoot->makeHTTPRequest(dl);
return c; return c;
} }
@@ -211,13 +156,10 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
return NULL; return NULL;
} }
bool versionCheckOk = checkVersion(aRoot->applicationVersion(), props); if (props->getStringValue("version") != aRoot->catalogVersion()) {
SG_LOG(SG_GENERAL, SG_WARN, "skipping catalog at " << aPath << ", version mismatch:\n\t"
if (!versionCheckOk) { << props->getStringValue("version") << " vs required " << aRoot->catalogVersion());
SG_LOG(SG_GENERAL, SG_INFO, "catalog at:" << aPath << " failed version check: need" << aRoot->applicationVersion()); return NULL;
// keep the catalog but mark it as needing an update
} else {
SG_LOG(SG_GENERAL, SG_DEBUG, "creating catalog from:" << aPath);
} }
CatalogRef c = new Catalog(aRoot); CatalogRef c = new Catalog(aRoot);
@@ -225,43 +167,9 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
c->parseProps(props); c->parseProps(props);
c->parseTimestamp(); c->parseTimestamp();
if (versionCheckOk) {
// parsed XML ok, mark status as valid
c->changeStatus(Delegate::STATUS_SUCCESS);
} else {
c->changeStatus(Delegate::FAIL_VERSION);
}
return c; return c;
} }
bool Catalog::uninstall()
{
bool ok;
bool atLeastOneFailure = false;
BOOST_FOREACH(PackageRef p, installedPackages()) {
ok = p->existingInstall()->uninstall();
if (!ok) {
SG_LOG(SG_GENERAL, SG_WARN, "uninstall of package " <<
p->id() << " failed");
// continue trying other packages, bailing out here
// gains us nothing
atLeastOneFailure = true;
}
}
Dir d(m_installRoot);
ok = d.remove(true /* recursive */);
if (!ok) {
atLeastOneFailure = true;
}
changeStatus(atLeastOneFailure ? Delegate::FAIL_FILESYSTEM
: Delegate::STATUS_SUCCESS);
return ok;
}
PackageList const& PackageList const&
Catalog::packages() const Catalog::packages() const
{ {
@@ -308,30 +216,29 @@ Catalog::installedPackages() const
return r; return r;
} }
void Catalog::refresh() InstallRef Catalog::installForPackage(PackageRef pkg) const
{ {
if (m_refreshRequest.valid()) { PackageInstallDict::const_iterator it = m_installed.find(pkg);
// refresh in progress if (it == m_installed.end()) {
return; // check if it exists on disk, create
SGPath p(pkg->pathOnDisk());
if (p.exists()) {
return Install::createFromPath(p, CatalogRef(const_cast<Catalog*>(this)));
} }
Downloader* dl = new Downloader(this, url()); return NULL;
m_refreshRequest = dl; }
// will update status to IN_PROGRESS
m_root->makeHTTPRequest(dl); return it->second;
} }
struct FindById void Catalog::refresh()
{ {
FindById(const std::string &id) : m_id(id) {} Downloader* dl = new Downloader(this, url());
m_root->makeHTTPRequest(dl);
bool operator()(const PackageRef& ref) const m_root->catalogRefreshBegin(this);
{ }
return ref->id() == m_id;
}
std::string m_id;
};
void Catalog::parseProps(const SGPropertyNode* aProps) void Catalog::parseProps(const SGPropertyNode* aProps)
{ {
@@ -346,14 +253,8 @@ void Catalog::parseProps(const SGPropertyNode* aProps)
for (int i = 0; i < nChildren; i++) { for (int i = 0; i < nChildren; i++) {
const SGPropertyNode* pkgProps = aProps->getChild(i); const SGPropertyNode* pkgProps = aProps->getChild(i);
if (strcmp(pkgProps->getName(), "package") == 0) { if (strcmp(pkgProps->getName(), "package") == 0) {
// can't use getPackageById here becuase the variant dict isn't PackageRef p = getPackageById(pkgProps->getStringValue("id"));
// built yet. Instead we need to look at m_packages directly. if (p) {
PackageList::iterator pit = std::find_if(m_packages.begin(), m_packages.end(),
FindById(pkgProps->getStringValue("id")));
PackageRef p;
if (pit != m_packages.end()) {
p = *pit;
// existing package // existing package
p->updateFromProps(pkgProps); p->updateFromProps(pkgProps);
orphans.erase(p); // not an orphan orphans.erase(p); // not an orphan
@@ -411,23 +312,11 @@ PackageRef Catalog::getPackageById(const std::string& aId) const
// works as expected. // works as expected.
PackageWeakMap::const_iterator it = m_variantDict.find(aId); PackageWeakMap::const_iterator it = m_variantDict.find(aId);
if (it == m_variantDict.end()) if (it == m_variantDict.end())
return PackageRef(); return NULL;
return it->second; return it->second;
} }
PackageRef Catalog::getPackageByPath(const std::string& aPath) const
{
PackageList::const_iterator it;
for (it = m_packages.begin(); it != m_packages.end(); ++it) {
if ((*it)->dirName() == aPath) {
return *it;
}
}
return PackageRef();
}
std::string Catalog::id() const std::string Catalog::id() const
{ {
return m_props->getStringValue("id"); return m_props->getStringValue("id");
@@ -438,11 +327,6 @@ std::string Catalog::url() const
return m_url; return m_url;
} }
std::string Catalog::name() const
{
return getLocalisedString(m_props, "name");
}
std::string Catalog::description() const std::string Catalog::description() const
{ {
return getLocalisedString(m_props, "description"); return getLocalisedString(m_props, "description");
@@ -479,21 +363,12 @@ unsigned int Catalog::ageInSeconds() const
bool Catalog::needsRefresh() const bool Catalog::needsRefresh() const
{ {
// always refresh in these cases
if ((m_status == Delegate::FAIL_VERSION) || (m_status == Delegate::FAIL_DOWNLOAD)) {
return true;
}
unsigned int maxAge = m_props->getIntValue("max-age-sec", m_root->maxAgeSeconds()); unsigned int maxAge = m_props->getIntValue("max-age-sec", m_root->maxAgeSeconds());
return (ageInSeconds() > maxAge); return (ageInSeconds() > maxAge);
} }
std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
{ {
if (!aRoot) {
return std::string();
}
if (aRoot->hasChild(m_root->getLocale())) { if (aRoot->hasChild(m_root->getLocale())) {
const SGPropertyNode* localeRoot = aRoot->getChild(m_root->getLocale().c_str()); const SGPropertyNode* localeRoot = aRoot->getChild(m_root->getLocale().c_str());
if (localeRoot->hasChild(aName)) { if (localeRoot->hasChild(aName)) {
@@ -504,31 +379,27 @@ std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char*
return aRoot->getStringValue(aName); return aRoot->getStringValue(aName);
} }
void Catalog::refreshComplete(Delegate::StatusCode aReason) void Catalog::refreshComplete(Delegate::FailureCode aReason)
{ {
changeStatus(aReason); m_root->catalogRefreshComplete(this, aReason);
m_refreshRequest.reset();
} }
void Catalog::changeStatus(Delegate::StatusCode newStatus) void Catalog::registerInstall(Install* ins)
{ {
if (m_status == newStatus) { if (!ins || ins->package()->catalog() != this) {
return; return;
} }
m_status = newStatus; m_installed[ins->package()] = ins;
m_root->catalogRefreshStatus(this, newStatus);
m_statusCallbacks(this);
} }
void Catalog::addStatusCallback(const Callback& cb) void Catalog::unregisterInstall(Install* ins)
{ {
m_statusCallbacks.push_back(cb); if (!ins || ins->package()->catalog() != this) {
} return;
}
Delegate::StatusCode Catalog::status() const m_installed.erase(ins->package());
{
return m_status;
} }
} // of namespace pkg } // of namespace pkg
+12 -30
View File
@@ -22,15 +22,11 @@
#include <ctime> #include <ctime>
#include <map> #include <map>
#include <boost/bind.hpp>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx> #include <simgear/props/props.hxx>
#include <simgear/structure/SGReferenced.hxx> #include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/function_list.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <simgear/package/Delegate.hxx> #include <simgear/package/Delegate.hxx>
@@ -64,14 +60,11 @@ public:
static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath); static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath);
static CatalogList allCatalogs();
Root* root() const Root* root() const
{ return m_root;}; { return m_root;};
/**
* uninstall this catalog entirely, including all installed packages
*/
bool uninstall();
/** /**
* perform a refresh of the catalog contents * perform a refresh of the catalog contents
*/ */
@@ -106,13 +99,11 @@ public:
std::string url() const; std::string url() const;
std::string name() const;
std::string description() const; std::string description() const;
PackageRef getPackageById(const std::string& aId) const; PackageRef getPackageById(const std::string& aId) const;
PackageRef getPackageByPath(const std::string& aPath) const; InstallRef installForPackage(PackageRef pkg) const;
/** /**
* test if the catalog data was retrieved longer ago than the * test if the catalog data was retrieved longer ago than the
@@ -126,41 +117,29 @@ public:
* access the raw property data in the catalog * access the raw property data in the catalog
*/ */
SGPropertyNode* properties() const; SGPropertyNode* properties() const;
Delegate::StatusCode status() const;
typedef boost::function<void(Catalog*)> Callback;
void addStatusCallback(const Callback& cb);
template<class C>
void addStatusCallback(C* instance, void (C::*mem_func)(Catalog*))
{
return addStatusCallback(boost::bind(mem_func, instance, _1));
}
private: private:
Catalog(Root* aRoot); Catalog(Root* aRoot);
class Downloader; class Downloader;
friend class Downloader; friend class Downloader;
friend class Install;
void registerInstall(Install* ins);
void unregisterInstall(Install* ins);
void parseProps(const SGPropertyNode* aProps); void parseProps(const SGPropertyNode* aProps);
void refreshComplete(Delegate::StatusCode aReason); void refreshComplete(Delegate::FailureCode aReason);
void parseTimestamp(); void parseTimestamp();
void writeTimestamp(); void writeTimestamp();
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const; std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const;
void changeStatus(Delegate::StatusCode newStatus);
Root* m_root; Root* m_root;
SGPropertyNode_ptr m_props; SGPropertyNode_ptr m_props;
SGPath m_installRoot; SGPath m_installRoot;
std::string m_url; std::string m_url;
Delegate::StatusCode m_status;
HTTP::Request_ptr m_refreshRequest;
PackageList m_packages; PackageList m_packages;
time_t m_retrievedTime; time_t m_retrievedTime;
@@ -168,7 +147,10 @@ private:
typedef std::map<std::string, Package*> PackageWeakMap; typedef std::map<std::string, Package*> PackageWeakMap;
PackageWeakMap m_variantDict; PackageWeakMap m_variantDict;
function_list<Callback> m_statusCallbacks; // important that this is a weak-ref to Installs,
// since it is only cleaned up in the Install destructor
typedef std::map<PackageRef, Install*> PackageInstallDict;
PackageInstallDict m_installed;
}; };
} // of namespace pkg } // of namespace pkg
-107
View File
@@ -1,107 +0,0 @@
// Copyright (C) 2015 James Turner - zakalawe@mac.com
//
// 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.
//
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/misc/test_macros.hxx>
#include <cstdlib>
#include <iostream>
#include <simgear/package/Catalog.hxx>
#include <simgear/package/Root.hxx>
#include <simgear/package/Package.hxx>
#include <simgear/misc/sg_dir.hxx>
using namespace simgear;
int parseTest()
{
SGPath rootPath = simgear::Dir::current().path();
rootPath.append("testRoot");
pkg::Root* root = new pkg::Root(rootPath, "8.1.12");
pkg::CatalogRef cat = pkg::Catalog::createFromPath(root, SGPath(SRC_DIR "/catalogTest1"));
VERIFY(cat.valid());
COMPARE(cat->id(), "org.flightgear.test.catalog1");
COMPARE(cat->url(), "http://download.flightgear.org/catalog1/catalog.xml");
COMPARE(cat->description(), "First test catalog");
// check the packages too
COMPARE(cat->packages().size(), 3);
pkg::PackageRef p1 = cat->packages().front();
COMPARE(p1->catalog(), cat.ptr());
COMPARE(p1->id(), "alpha");
COMPARE(p1->qualifiedId(), "org.flightgear.test.catalog1.alpha");
COMPARE(p1->name(), "Alpha package");
COMPARE(p1->revision(), 8);
COMPARE(p1->fileSizeBytes(), 1234567);
pkg::PackageRef p2 = cat->getPackageById("c172p");
VERIFY(p2.valid());
COMPARE(p2->qualifiedId(), "org.flightgear.test.catalog1.c172p");
COMPARE(p2->description(), "A plane made by Cessna");
// test filtering / searching too
string_set tags(p2->tags());
COMPARE(tags.size(), 4);
VERIFY(tags.find("ifr") != tags.end());
VERIFY(tags.find("cessna") != tags.end());
VERIFY(tags.find("jet") == tags.end());
SGPropertyNode_ptr queryA(new SGPropertyNode);
queryA->setStringValue("tag", "ifr");
VERIFY(p2->matches(queryA.ptr()));
SGPropertyNode_ptr queryB(new SGPropertyNode);
queryB->setStringValue("name", "ces");
VERIFY(p2->matches(queryB.ptr()));
SGPropertyNode_ptr queryC(new SGPropertyNode);
queryC->setStringValue("name", "foo");
VERIFY(!p2->matches(queryC.ptr()));
SGPropertyNode_ptr queryD(new SGPropertyNode);
queryD->setIntValue("rating-FDM", 3);
VERIFY(p2->matches(queryD.ptr()));
SGPropertyNode_ptr queryE(new SGPropertyNode);
queryE->setIntValue("rating-model", 5);
queryE->setStringValue("description", "cessna");
VERIFY(p2->matches(queryE.ptr()));
delete root;
return EXIT_SUCCESS;
}
int main(int argc, char* argv[])
{
parseTest();
std::cout << "Successfully passed all tests!" << std::endl;
return EXIT_SUCCESS;
}
+17 -25
View File
@@ -18,9 +18,6 @@
#ifndef SG_PACKAGE_DELEGATE_HXX #ifndef SG_PACKAGE_DELEGATE_HXX
#define SG_PACKAGE_DELEGATE_HXX #define SG_PACKAGE_DELEGATE_HXX
#include <simgear/misc/stdint.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
namespace simgear namespace simgear
{ {
@@ -30,9 +27,6 @@ namespace pkg
class Install; class Install;
class Catalog; class Catalog;
typedef SGSharedPtr<Catalog> CatalogRef;
typedef SGSharedPtr<Install> InstallRef;
/** /**
* package delegate is the mechanism to discover progress / completion / * package delegate is the mechanism to discover progress / completion /
* errors in packaging steps asynchronously. * errors in packaging steps asynchronously.
@@ -41,40 +35,38 @@ class Delegate
{ {
public: public:
typedef enum { typedef enum {
STATUS_SUCCESS = 0, FAIL_SUCCESS = 0, ///< not a failure :)
FAIL_UNKNOWN = 1, FAIL_UNKNOWN = 1,
STATUS_IN_PROGRESS, ///< downloading/installation in progress FAIL_IN_PROGRESS, ///< downloading/installation in progress (not a failure :P)
FAIL_CHECKSUM, ///< package MD5 verificstion failed FAIL_CHECKSUM, ///< package MD5 verificstion failed
FAIL_DOWNLOAD, ///< network issue FAIL_DOWNLOAD, ///< network issue
FAIL_EXTRACT, ///< package archive failed to extract cleanly FAIL_EXTRACT, ///< package archive failed to extract cleanly
FAIL_FILESYSTEM, ///< unknown filesystem error occurred FAIL_FILESYSTEM, ///< unknown filesystem error occurred
FAIL_VERSION, ///< version check mismatch FAIL_VERSION ///< version check mismatch
FAIL_NOT_FOUND, ///< package URL returned a 404 } FailureCode;
STATUS_REFRESHED,
USER_CANCELLED
} StatusCode;
virtual ~Delegate() { } virtual ~Delegate() { }
/**
* invoked when all catalogs have finished refreshing - either successfully
* or with a failure.
*/
virtual void refreshComplete() = 0;
/** /**
* emitted when a catalog refesh completes, either success or failure * emitted when a catalog fails to refresh, due to a network issue or
* If catalog is null, this means /all/ catalogs have been refreshed * some other failure.
*/ */
virtual void catalogRefreshed(CatalogRef, StatusCode aReason) = 0; virtual void failedRefresh(Catalog*, FailureCode aReason) = 0;
virtual void startInstall(InstallRef aInstall) = 0; virtual void startInstall(Install* aInstall) = 0;
virtual void installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal) = 0; virtual void installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal) = 0;
virtual void finishInstall(InstallRef aInstall, StatusCode aReason) = 0; virtual void finishInstall(Install* aInstall) = 0;
/**
* Notification when catalogs/packages are added or removed
*/
virtual void availablePackagesChanged() {}
virtual void dataForThumbnail(const std::string& aThumbnailUrl, virtual void failedInstall(Install* aInstall, FailureCode aReason) = 0;
size_t lenth, const uint8_t* bytes) {}
}; };
} // of namespace pkg } // of namespace pkg
+34 -168
View File
@@ -24,7 +24,6 @@
#include <simgear/package/md5.h> #include <simgear/package/md5.h>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/package/Catalog.hxx> #include <simgear/package/Catalog.hxx>
#include <simgear/package/Package.hxx> #include <simgear/package/Package.hxx>
#include <simgear/package/Root.hxx> #include <simgear/package/Root.hxx>
@@ -46,8 +45,7 @@ class Install::PackageArchiveDownloader : public HTTP::Request
public: public:
PackageArchiveDownloader(InstallRef aOwner) : PackageArchiveDownloader(InstallRef aOwner) :
HTTP::Request("" /* dummy URL */), HTTP::Request("" /* dummy URL */),
m_owner(aOwner), m_owner(aOwner)
m_downloaded(0)
{ {
m_urls = m_owner->package()->downloadUrls(); m_urls = m_owner->package()->downloadUrls();
if (m_urls.empty()) { if (m_urls.empty()) {
@@ -57,39 +55,10 @@ public:
// TODO randomise order of m_urls // TODO randomise order of m_urls
m_extractPath = aOwner->path().dir(); m_extractPath = aOwner->path().dir();
m_extractPath.append("_extract_" + aOwner->package()->md5()); m_extractPath.append("_DOWNLOAD"); // add some temporary value
// clean up any existing files
Dir d(m_extractPath);
if (d.exists()) {
d.remove(true /* recursive */);
}
} }
~PackageArchiveDownloader()
{
// always clean up our extraction dir: if we successfully downloaded
// and installed it will be an empty dir, if we failed it might contain
// (some) of the package files.
Dir d(m_extractPath);
if (d.exists()) {
d.remove(true /* recursive */);
}
}
size_t downloadedBytes() const
{
return m_downloaded;
}
int percentDownloaded() const
{
if (responseLength() <= 0) {
return 0;
}
return (m_downloaded * 100) / responseLength();
}
protected: protected:
virtual std::string url() const virtual std::string url() const
{ {
@@ -98,8 +67,6 @@ protected:
virtual void responseHeadersComplete() virtual void responseHeadersComplete()
{ {
Request::responseHeadersComplete();
Dir d(m_extractPath); Dir d(m_extractPath);
d.create(0755); d.create(0755);
@@ -112,21 +79,14 @@ protected:
m_buffer += std::string(s, n); m_buffer += std::string(s, n);
SG_MD5Update(&m_md5, (unsigned char*) s, n); SG_MD5Update(&m_md5, (unsigned char*) s, n);
m_downloaded = m_buffer.size();
m_owner->installProgress(m_buffer.size(), responseLength()); m_owner->installProgress(m_buffer.size(), responseLength());
} }
virtual void onDone() virtual void onDone()
{ {
if (responseCode() != 200) { if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "download failure:" << responseCode() << SG_LOG(SG_GENERAL, SG_ALERT, "download failure");
"\n\t" << url()); doFailure(Delegate::FAIL_DOWNLOAD);
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
if (responseCode() == 404) {
code = Delegate::FAIL_NOT_FOUND;
}
doFailure(code);
return; return;
} }
@@ -151,16 +111,13 @@ protected:
} }
if (m_owner->path().exists()) { if (m_owner->path().exists()) {
//std::cout << "removing existing path" << std::endl;
Dir destDir(m_owner->path()); Dir destDir(m_owner->path());
destDir.remove(true /* recursive */); destDir.remove(true /* recursive */);
} }
// build a path like /path/to/packages/org.some.catalog/Aircraft/extract_xxxx/MyAircraftDir m_extractPath.append(m_owner->package()->id());
SGPath extractedPath = m_extractPath; bool ok = m_extractPath.rename(m_owner->path());
extractedPath.append(m_owner->package()->dirName());
// rename it to path/to/packages/org.some.catalog/Aircraft/MyAircraftDir
bool ok = extractedPath.rename(m_owner->path());
if (!ok) { if (!ok) {
doFailure(Delegate::FAIL_FILESYSTEM); doFailure(Delegate::FAIL_FILESYSTEM);
return; return;
@@ -168,18 +125,7 @@ protected:
m_owner->m_revision = m_owner->package()->revision(); m_owner->m_revision = m_owner->package()->revision();
m_owner->writeRevisionFile(); m_owner->writeRevisionFile();
m_owner->m_download.reset(); // so isDownloading reports false m_owner->installResult(Delegate::FAIL_SUCCESS);
m_owner->installResult(Delegate::STATUS_SUCCESS);
}
virtual void onFail()
{
if (responseCode() == -1) {
doFailure(Delegate::USER_CANCELLED);
} else {
doFailure(Delegate::FAIL_DOWNLOAD);
}
} }
private: private:
@@ -282,16 +228,19 @@ private:
return result; return result;
} }
void doFailure(Delegate::StatusCode aReason) void doFailure(Delegate::FailureCode aReason)
{ {
Dir dir(m_extractPath); Dir dir(m_extractPath);
if (dir.exists()) {
dir.remove(true /* recursive */); dir.remove(true /* recursive */);
if (m_urls.size() == 1) {
std::cout << "failure:" << aReason << std::endl;
m_owner->installResult(aReason);
return;
} }
// TODO - try other mirrors std::cout << "retrying download" << std::endl;
m_owner->m_download.reset(); // ensure we get cleaned up m_urls.erase(m_urls.begin()); // pop first URL
m_owner->installResult(aReason);
} }
InstallRef m_owner; InstallRef m_owner;
@@ -299,29 +248,30 @@ private:
SG_MD5_CTX m_md5; SG_MD5_CTX m_md5;
std::string m_buffer; std::string m_buffer;
SGPath m_extractPath; SGPath m_extractPath;
size_t m_downloaded;
}; };
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
Install::Install(PackageRef aPkg, const SGPath& aPath) : Install::Install(PackageRef aPkg, const SGPath& aPath) :
m_package(aPkg), m_package(aPkg),
m_path(aPath), m_path(aPath),
m_status(Delegate::STATUS_IN_PROGRESS) m_download(NULL),
_status(Delegate::FAIL_IN_PROGRESS)
{ {
parseRevision(); parseRevision();
m_package->catalog()->root()->registerInstall(this); m_package->catalog()->registerInstall(this);
} }
Install::~Install() Install::~Install()
{ {
m_package->catalog()->unregisterInstall(this);
} }
InstallRef Install::createFromPath(const SGPath& aPath, CatalogRef aCat) InstallRef Install::createFromPath(const SGPath& aPath, CatalogRef aCat)
{ {
std::string path = aPath.file(); std::string id = aPath.file();
PackageRef pkg = aCat->getPackageByPath(path); PackageRef pkg = aCat->getPackageById(id);
if (!pkg) if (!pkg)
throw sg_exception("no package with path:" + path); throw sg_exception("no package with id:" + id);
return new Install(pkg, aPath); return new Install(pkg, aPath);
} }
@@ -363,102 +313,17 @@ void Install::startUpdate()
m_package->catalog()->root()->startInstall(this); m_package->catalog()->root()->startInstall(this);
} }
bool Install::uninstall() void Install::uninstall()
{ {
Dir d(m_path); Dir d(m_path);
if (!d.remove(true)) { d.remove(true);
SG_LOG(SG_GENERAL, SG_ALERT, "package uninstall failed: couldn't remove path " << m_path); m_package->catalog()->unregisterInstall(this);
return false;
}
m_package->catalog()->root()->unregisterInstall(this);
return true;
}
bool Install::isDownloading() const
{
return (m_download.valid());
}
bool Install::isQueued() const
{
return m_package->catalog()->root()->isInstallQueued(const_cast<Install*>(this));
}
int Install::downloadedPercent() const
{
if (!m_download.valid()) {
return -1;
}
PackageArchiveDownloader* dl = static_cast<PackageArchiveDownloader*>(m_download.get());
return dl->percentDownloaded();
}
size_t Install::downloadedBytes() const
{
if (!m_download.valid()) {
return -1;
}
PackageArchiveDownloader* dl = static_cast<PackageArchiveDownloader*>(m_download.get());
return dl->downloadedBytes();
}
void Install::cancelDownload()
{
if (m_download.valid()) {
m_download->abort("User cancelled download");
}
if (m_revision == 0) {
SG_LOG(SG_GENERAL, SG_INFO, "cancel install of package, will unregister");
m_package->catalog()->root()->unregisterInstall(this);
}
m_package->catalog()->root()->cancelDownload(this);
}
struct PathAppender
{
PathAppender(const SGPath& p) : m_path(p) {}
SGPath operator()(const std::string& s) const
{
SGPath p(m_path);
p.append(s);
return p;
}
SGPath m_path;
};
PathList Install::thumbnailPaths() const
{
const string_list& thumbs(m_package->thumbnails());
PathList result;
if (thumbs.empty())
return result;
std::transform(thumbs.begin(), thumbs.end(),
std::back_inserter(result),
PathAppender(m_path));
return result;
}
SGPath Install::primarySetPath() const
{
SGPath setPath(m_path);
std::string ps(m_package->id());
setPath.append(ps + "-set.xml");
return setPath;
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Install* Install::done(const Callback& cb) Install* Install::done(const Callback& cb)
{ {
if( m_status == Delegate::STATUS_SUCCESS ) if( _status == Delegate::FAIL_SUCCESS )
cb(this); cb(this);
else else
_cb_done.push_back(cb); _cb_done.push_back(cb);
@@ -469,8 +334,8 @@ Install* Install::done(const Callback& cb)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Install* Install::fail(const Callback& cb) Install* Install::fail(const Callback& cb)
{ {
if( m_status != Delegate::STATUS_SUCCESS if( _status != Delegate::FAIL_SUCCESS
&& m_status != Delegate::STATUS_IN_PROGRESS ) && _status != Delegate::FAIL_IN_PROGRESS )
cb(this); cb(this);
else else
_cb_fail.push_back(cb); _cb_fail.push_back(cb);
@@ -481,7 +346,7 @@ Install* Install::fail(const Callback& cb)
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
Install* Install::always(const Callback& cb) Install* Install::always(const Callback& cb)
{ {
if( m_status != Delegate::STATUS_IN_PROGRESS ) if( _status != Delegate::FAIL_IN_PROGRESS )
cb(this); cb(this);
else else
_cb_always.push_back(cb); _cb_always.push_back(cb);
@@ -497,12 +362,13 @@ Install* Install::progress(const ProgressCallback& cb)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
void Install::installResult(Delegate::StatusCode aReason) void Install::installResult(Delegate::FailureCode aReason)
{ {
m_package->catalog()->root()->finishInstall(this, aReason); if (aReason == Delegate::FAIL_SUCCESS) {
if (aReason == Delegate::STATUS_SUCCESS) { m_package->catalog()->root()->finishInstall(this);
_cb_done(this); _cb_done(this);
} else { } else {
m_package->catalog()->root()->failedInstall(this, aReason);
_cb_fail(this); _cb_fail(this);
} }
+4 -33
View File
@@ -21,13 +21,11 @@
#include <vector> #include <vector>
#include <simgear/misc/sg_path.hxx> #include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <simgear/package/Delegate.hxx> #include <simgear/package/Delegate.hxx>
#include <simgear/structure/function_list.hxx> #include <simgear/structure/function_list.hxx>
#include <simgear/structure/SGReferenced.hxx> #include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <boost/bind.hpp> #include <boost/bind.hpp>
@@ -76,34 +74,7 @@ public:
void startUpdate(); void startUpdate();
bool uninstall(); void uninstall();
bool isDownloading() const;
bool isQueued() const;
int downloadedPercent() const;
size_t downloadedBytes() const;
/**
* full path to the primary -set.xml file for this install
*/
SGPath primarySetPath() const;
/**
* if a download is in progress, cancel it. If this is the first install
* of the package (as opposed to an update), the install will be cleaned
* up once the last reference is gone.
*/
void cancelDownload();
/**
* return the thumbnails associated with this install, but as locations
* on the file system, not URLs. It is assumed the order of thumbnails
* is consistent with the URLs returned from Package::thumbnailUrls()
*/
PathList thumbnailPaths() const;
/** /**
* Set the handler to be called when the installation successfully * Set the handler to be called when the installation successfully
@@ -174,16 +145,16 @@ private:
void parseRevision(); void parseRevision();
void writeRevisionFile(); void writeRevisionFile();
void installResult(Delegate::StatusCode aReason); void installResult(Delegate::FailureCode aReason);
void installProgress(unsigned int aBytes, unsigned int aTotal); void installProgress(unsigned int aBytes, unsigned int aTotal);
PackageRef m_package; PackageRef m_package;
unsigned int m_revision; ///< revision on disk unsigned int m_revision; ///< revision on disk
SGPath m_path; ///< installation point on disk SGPath m_path; ///< installation point on disk
HTTP::Request_ptr m_download; PackageArchiveDownloader* m_download;
Delegate::StatusCode m_status; Delegate::FailureCode _status;
function_list<Callback> _cb_done, function_list<Callback> _cb_done,
_cb_fail, _cb_fail,
+3 -65
View File
@@ -117,7 +117,7 @@ SGPath Package::pathOnDisk() const
{ {
SGPath p(m_catalog->installRoot()); SGPath p(m_catalog->installRoot());
p.append("Aircraft"); p.append("Aircraft");
p.append(dirName()); p.append(id());
return p; return p;
} }
@@ -139,12 +139,7 @@ InstallRef Package::install()
InstallRef Package::existingInstall(const InstallCallback& cb) const InstallRef Package::existingInstall(const InstallCallback& cb) const
{ {
InstallRef install; InstallRef install = m_catalog->installForPackage(const_cast<Package*>(this));
try {
install = m_catalog->root()->existingInstallForPackage(const_cast<Package*>(this));
} catch (std::exception& e) {
return InstallRef();
}
if( cb ) if( cb )
{ {
@@ -167,30 +162,13 @@ std::string Package::qualifiedId() const
return m_catalog->id() + "." + id(); return m_catalog->id() + "." + id();
} }
std::string Package::qualifiedVariantId(const unsigned int variantIndex) const
{
return m_catalog->id() + "." + variants()[variantIndex];
}
std::string Package::md5() const std::string Package::md5() const
{ {
return m_props->getStringValue("md5"); return m_props->getStringValue("md5");
} }
std::string Package::dirName() const
{
std::string r(m_props->getStringValue("dir"));
if (r.empty())
throw sg_exception("missing dir property on catalog package entry for " + m_id);
return r;
}
unsigned int Package::revision() const unsigned int Package::revision() const
{ {
if (!m_props) {
return 0;
}
return m_props->getIntValue("revision"); return m_props->getIntValue("revision");
} }
@@ -209,11 +187,6 @@ std::string Package::description() const
return getLocalisedProp("description"); return getLocalisedProp("description");
} }
string_set Package::tags() const
{
return m_tags;
}
SGPropertyNode* Package::properties() const SGPropertyNode* Package::properties() const
{ {
return m_props.ptr(); return m_props.ptr();
@@ -222,36 +195,15 @@ SGPropertyNode* Package::properties() const
string_list Package::thumbnailUrls() const string_list Package::thumbnailUrls() const
{ {
string_list r; string_list r;
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) { BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
r.push_back(dl->getStringValue()); r.push_back(dl->getStringValue());
} }
return r; return r;
} }
string_list Package::thumbnails() const
{
string_list r;
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail-path")) {
r.push_back(dl->getStringValue());
}
return r;
}
string_list Package::downloadUrls() const string_list Package::downloadUrls() const
{ {
string_list r; string_list r;
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("url")) { BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("url")) {
r.push_back(dl->getStringValue()); r.push_back(dl->getStringValue());
} }
@@ -286,7 +238,7 @@ PackageList Package::dependencies() const
// prefer local hangar package if possible, in case someone does something // prefer local hangar package if possible, in case someone does something
// silly with naming. Of course flightgear's aircraft search doesn't know // silly with naming. Of course flightgear's aircraft search doesn't know
// about hangars, so names still need to be unique. // about hanagrs, so names still need to be unique.
PackageRef depPkg = m_catalog->getPackageById(depName); PackageRef depPkg = m_catalog->getPackageById(depName);
if (!depPkg) { if (!depPkg) {
Root* rt = m_catalog->root(); Root* rt = m_catalog->root();
@@ -338,20 +290,6 @@ std::string Package::nameForVariant(const std::string& vid) const
throw sg_exception("Unknow variant +" + vid + " in package " + id()); throw sg_exception("Unknow variant +" + vid + " in package " + id());
} }
std::string Package::nameForVariant(const unsigned int vIndex) const
{
if (vIndex == 0)
return name();
// offset by minus one to allow for index 0 being the primary
SGPropertyNode_ptr var = m_props->getChild("variant", vIndex - 1);
if (var)
return var->getStringValue("name");
throw sg_exception("Unknow variant in package " + id());
}
} // of namespace pkg } // of namespace pkg
} // of namespace simgear } // of namespace simgear
-21
View File
@@ -76,11 +76,6 @@ public:
*/ */
std::string qualifiedId() const; std::string qualifiedId() const;
/**
* Fully-qualified ID, including our catalog'd ID
*/
std::string qualifiedVariantId(const unsigned int variantIndex) const;
/** /**
* human-readable name - note this is probably not localised, * human-readable name - note this is probably not localised,
* although this is not ruled out for the future. * although this is not ruled out for the future.
@@ -92,8 +87,6 @@ public:
*/ */
std::string nameForVariant(const std::string& vid) const; std::string nameForVariant(const std::string& vid) const;
std::string nameForVariant(const unsigned int vIndex) const;
/** /**
* syntactic sugar to get the localised description * syntactic sugar to get the localised description
*/ */
@@ -120,8 +113,6 @@ public:
bool matches(const SGPropertyNode* aFilter) const; bool matches(const SGPropertyNode* aFilter) const;
string_set tags() const;
/** /**
* download URLs for the package * download URLs for the package
*/ */
@@ -129,28 +120,16 @@ public:
string_list thumbnailUrls() const; string_list thumbnailUrls() const;
/**
* thumbnail file paths within the package on disk
*/
string_list thumbnails() const;
/** /**
* Packages we depend upon. * Packages we depend upon.
* If the dependency list cannot be satisifed for some reason, * If the dependency list cannot be satisifed for some reason,
* this will raise an sg_exception. * this will raise an sg_exception.
*/ */
PackageList dependencies() const; PackageList dependencies() const;
/**
* Name of the package directory on disk. This may or may not be the
* same as the primary ID, depending on the aircraft author
*/
std::string dirName() const;
private: private:
SGPath pathOnDisk() const; SGPath pathOnDisk() const;
friend class Catalog; friend class Catalog;
friend class Root;
Package(const SGPropertyNode* aProps, CatalogRef aCatalog); Package(const SGPropertyNode* aProps, CatalogRef aCatalog);
+47 -348
View File
@@ -38,159 +38,31 @@ namespace simgear {
namespace pkg { namespace pkg {
typedef std::map<std::string, CatalogRef> CatalogDict; typedef std::map<std::string, CatalogRef> CatalogDict;
typedef std::vector<Delegate*> DelegateVec;
typedef std::map<std::string, std::string> MemThumbnailCache;
typedef std::deque<std::string> StringDeque;
class Root::ThumbnailDownloader : public HTTP::Request
{
public:
ThumbnailDownloader(Root::RootPrivate* aOwner, const std::string& aUrl) :
HTTP::Request(aUrl),
m_owner(aOwner)
{
}
protected:
virtual void gotBodyData(const char* s, int n)
{
m_buffer += std::string(s, n);
}
virtual void onDone();
private:
Root::RootPrivate* m_owner;
std::string m_buffer;
};
class Root::RootPrivate class Root::RootPrivate
{ {
public: public:
RootPrivate() : RootPrivate() :
http(NULL), http(NULL),
maxAgeSeconds(60 * 60 * 24) maxAgeSeconds(60 * 60 * 24),
delegate(NULL)
{ {
}
void fireStartInstall(InstallRef install)
{
DelegateVec::const_iterator it;
for (it = delegates.begin(); it != delegates.end(); ++it) {
(*it)->startInstall(install);
} }
}
void fireInstallProgress(InstallRef install,
unsigned int aBytes, unsigned int aTotal)
{
DelegateVec::const_iterator it;
for (it = delegates.begin(); it != delegates.end(); ++it) {
(*it)->installProgress(install, aBytes, aTotal);
}
}
void fireFinishInstall(InstallRef install, Delegate::StatusCode status)
{
DelegateVec::const_iterator it;
for (it = delegates.begin(); it != delegates.end(); ++it) {
(*it)->finishInstall(install, status);
}
}
void fireRefreshStatus(CatalogRef catalog, Delegate::StatusCode status)
{
DelegateVec::const_iterator it;
for (it = delegates.begin(); it != delegates.end(); ++it) {
(*it)->catalogRefreshed(catalog, status);
}
}
void firePackagesChanged()
{
DelegateVec::const_iterator it;
for (it = delegates.begin(); it != delegates.end(); ++it) {
(*it)->availablePackagesChanged();
}
}
void thumbnailDownloadComplete(HTTP::Request_ptr request,
Delegate::StatusCode status, const std::string& bytes)
{
std::string u(request->url());
if (status == Delegate::STATUS_SUCCESS) {
thumbnailCache[u] = bytes;
fireDataForThumbnail(u, bytes);
}
downloadNextPendingThumbnail();
}
void fireDataForThumbnail(const std::string& aUrl, const std::string& bytes)
{
DelegateVec::const_iterator it;
const uint8_t* data = reinterpret_cast<const uint8_t*>(bytes.data());
for (it = delegates.begin(); it != delegates.end(); ++it) {
(*it)->dataForThumbnail(aUrl, bytes.size(), data);
}
}
void downloadNextPendingThumbnail()
{
thumbnailDownloadRequest.clear();
if (pendingThumbnails.empty()) {
return;
}
std::string u = pendingThumbnails.front();
pendingThumbnails.pop_front();
thumbnailDownloadRequest = new Root::ThumbnailDownloader(this, u);
if (http) {
http->makeRequest(thumbnailDownloadRequest);
} else {
httpPendingRequests.push_back(thumbnailDownloadRequest);
}
}
DelegateVec delegates;
SGPath path; SGPath path;
std::string locale; std::string locale;
HTTP::Client* http; HTTP::Client* http;
CatalogDict catalogs; CatalogDict catalogs;
CatalogList disabledCatalogs;
unsigned int maxAgeSeconds; unsigned int maxAgeSeconds;
Delegate* delegate;
std::string version; std::string version;
std::set<CatalogRef> refreshing; std::set<CatalogRef> refreshing;
typedef std::deque<InstallRef> UpdateDeque; std::deque<InstallRef> updateDeque;
UpdateDeque updateDeque;
std::deque<HTTP::Request_ptr> httpPendingRequests; std::deque<HTTP::Request_ptr> httpPendingRequests;
HTTP::Request_ptr thumbnailDownloadRequest;
StringDeque pendingThumbnails;
MemThumbnailCache thumbnailCache;
typedef std::map<PackageRef, InstallRef> InstallCache;
InstallCache m_installs;
}; };
void Root::ThumbnailDownloader::onDone()
{
if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "thumbnail download failure:" << url());
m_owner->thumbnailDownloadComplete(this, Delegate::FAIL_DOWNLOAD, std::string());
return;
}
m_owner->thumbnailDownloadComplete(this, Delegate::STATUS_SUCCESS, m_buffer);
//time(&m_owner->m_retrievedTime);
//m_owner->writeTimestamp();
//m_owner->refreshComplete(Delegate::STATUS_REFRESHED);
}
SGPath Root::path() const SGPath Root::path() const
{ {
return d->path; return d->path;
@@ -241,16 +113,10 @@ Root::Root(const SGPath& aPath, const std::string& aVersion) :
return; return;
} }
BOOST_FOREACH(SGPath c, dir.children(Dir::TYPE_DIR | Dir::NO_DOT_OR_DOTDOT)) { BOOST_FOREACH(SGPath c, dir.children(Dir::TYPE_DIR)) {
CatalogRef cat = Catalog::createFromPath(this, c); CatalogRef cat = Catalog::createFromPath(this, c);
if (cat) { if (cat) {
if (cat->status() == Delegate::STATUS_SUCCESS) {
d->catalogs[cat->id()] = cat; d->catalogs[cat->id()] = cat;
} else {
// catalog has problems, such as needing an update
// keep it out of the main collection for now
d->disabledCatalogs.push_back(cat);
}
} }
} // of child directories iteration } // of child directories iteration
} }
@@ -260,12 +126,7 @@ Root::~Root()
} }
int Root::catalogVersion() const std::string Root::catalogVersion() const
{
return 4;
}
std::string Root::applicationVersion() const
{ {
return d->version; return d->version;
} }
@@ -319,20 +180,6 @@ CatalogList Root::catalogs() const
return r; return r;
} }
PackageList
Root::allPackages() const
{
PackageList r;
CatalogDict::const_iterator it = d->catalogs.begin();
for (; it != d->catalogs.end(); ++it) {
const PackageList& r2(it->second->packages());
r.insert(r.end(), r2.begin(), r2.end());
}
return r;
}
PackageList PackageList
Root::packagesMatching(const SGPropertyNode* aFilter) const Root::packagesMatching(const SGPropertyNode* aFilter) const
{ {
@@ -363,45 +210,17 @@ Root::packagesNeedingUpdate() const
void Root::refresh(bool aForce) void Root::refresh(bool aForce)
{ {
bool didStartAny = false;
// copy all candidate ctalogs to a seperate list, since refreshing
// can modify both the main collection and/or the disabled list
CatalogList toRefresh;
CatalogDict::iterator it = d->catalogs.begin(); CatalogDict::iterator it = d->catalogs.begin();
for (; it != d->catalogs.end(); ++it) { for (; it != d->catalogs.end(); ++it) {
toRefresh.push_back(it->second); if (aForce || it->second->needsRefresh()) {
it->second->refresh();
} }
toRefresh.insert(toRefresh.end(), d->disabledCatalogs.begin(),
d->disabledCatalogs.end());
CatalogList::iterator j = toRefresh.begin();
for (; j != toRefresh.end(); ++j) {
(*j)->refresh();
didStartAny = true;
}
if (!didStartAny) {
// signal refresh complete to the delegate already
d->fireRefreshStatus(CatalogRef(), Delegate::STATUS_REFRESHED);
} }
} }
void Root::addDelegate(simgear::pkg::Delegate *aDelegate) void Root::setDelegate(simgear::pkg::Delegate *aDelegate)
{ {
d->delegates.push_back(aDelegate); d->delegate = aDelegate;
}
void Root::removeDelegate(simgear::pkg::Delegate *aDelegate)
{
DelegateVec::iterator it = std::find(d->delegates.begin(),
d->delegates.end(), aDelegate);
if (it == d->delegates.end()) {
throw sg_exception("unknown delegate in removeDelegate");
}
d->delegates.erase(it);
} }
void Root::setLocale(const std::string& aLocale) void Root::setLocale(const std::string& aLocale)
@@ -435,21 +254,18 @@ void Root::scheduleToUpdate(InstallRef aInstall)
} }
} }
bool Root::isInstallQueued(InstallRef aInstall) const
{
RootPrivate::UpdateDeque::const_iterator it =
std::find(d->updateDeque.begin(), d->updateDeque.end(), aInstall);
return (it != d->updateDeque.end());
}
void Root::startInstall(InstallRef aInstall) void Root::startInstall(InstallRef aInstall)
{ {
d->fireStartInstall(aInstall); if (d->delegate) {
d->delegate->startInstall(aInstall.ptr());
}
} }
void Root::installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal) void Root::installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal)
{ {
d->fireInstallProgress(aInstall, aBytes, aTotal); if (d->delegate) {
d->delegate->installProgress(aInstall.ptr(), aBytes, aTotal);
}
} }
void Root::startNext(InstallRef aCurrent) void Root::startNext(InstallRef aCurrent)
@@ -465,176 +281,59 @@ void Root::startNext(InstallRef aCurrent)
} }
} }
void Root::finishInstall(InstallRef aInstall, Delegate::StatusCode aReason) void Root::finishInstall(InstallRef aInstall)
{
if (d->delegate) {
d->delegate->finishInstall(aInstall.ptr());
}
startNext(aInstall);
}
void Root::failedInstall(InstallRef aInstall, Delegate::FailureCode aReason)
{ {
if (aReason != Delegate::STATUS_SUCCESS) {
SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:" SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:"
<< aInstall->package()->id() << ":" << aReason); << aInstall->package()->id() << ":" << aReason);
if (d->delegate) {
d->delegate->failedInstall(aInstall.ptr(), aReason);
} }
// order matters here, so a call to 'isQueued' from a finish-install
// callback returns false, not true
startNext(aInstall); startNext(aInstall);
d->fireFinishInstall(aInstall, aReason);
} }
void Root::cancelDownload(InstallRef aInstall) void Root::catalogRefreshBegin(CatalogRef aCat)
{ {
RootPrivate::UpdateDeque::iterator it = d->refreshing.insert(aCat);
std::find(d->updateDeque.begin(), d->updateDeque.end(), aInstall);
if (it != d->updateDeque.end()) {
bool startNext = (aInstall == d->updateDeque.front());
d->updateDeque.erase(it);
if (startNext) {
if (!d->updateDeque.empty()) {
d->updateDeque.front()->startUpdate();
}
} // of install was front item
} // of found install in queue
} }
void Root::catalogRefreshStatus(CatalogRef aCat, Delegate::StatusCode aReason) void Root::catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason)
{ {
CatalogDict::iterator catIt = d->catalogs.find(aCat->id()); CatalogDict::iterator catIt = d->catalogs.find(aCat->id());
d->fireRefreshStatus(aCat, aReason); if (aReason != Delegate::FAIL_SUCCESS) {
if (d->delegate) {
if (aReason == Delegate::STATUS_IN_PROGRESS) { d->delegate->failedRefresh(aCat, aReason);
d->refreshing.insert(aCat);
} else {
d->refreshing.erase(aCat);
} }
if ((aReason == Delegate::STATUS_REFRESHED) && (catIt == d->catalogs.end())) { // if the failure is permanent, delete the catalog from our
assert(!aCat->id().empty()); // list (don't touch it on disk)
d->catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat)); bool isPermanentFailure = (aReason == Delegate::FAIL_VERSION);
if (isPermanentFailure) {
// catalog might have been previously disabled, let's remove in that case SG_LOG(SG_GENERAL, SG_WARN, "permanent failure for catalog:" << aCat->id());
CatalogList::iterator j = std::find(d->disabledCatalogs.begin(),
d->disabledCatalogs.end(),
aCat);
if (j != d->disabledCatalogs.end()) {
SG_LOG(SG_GENERAL, SG_INFO, "re-enabling disabled catalog:" << aCat->id());
d->disabledCatalogs.erase(j);
}
}
if ((aReason != Delegate::STATUS_REFRESHED) &&
(aReason != Delegate::STATUS_IN_PROGRESS) &&
(aReason != Delegate::STATUS_SUCCESS))
{
// catalog has errors, disable it
CatalogList::iterator j = std::find(d->disabledCatalogs.begin(),
d->disabledCatalogs.end(),
aCat);
if (j == d->disabledCatalogs.end()) {
SG_LOG(SG_GENERAL, SG_INFO, "disabling catalog:" << aCat->id());
d->disabledCatalogs.push_back(aCat);
}
// and remove it from the active collection
if (catIt != d->catalogs.end()) { if (catIt != d->catalogs.end()) {
d->catalogs.erase(catIt); d->catalogs.erase(catIt);
} }
} // of catalog has errors case }
} else if (catIt == d->catalogs.end()) {
// first fresh, add to our storage now
d->catalogs.insert(catIt, CatalogDict::value_type(aCat->id(), aCat));
}
d->refreshing.erase(aCat);
if (d->refreshing.empty()) { if (d->refreshing.empty()) {
d->fireRefreshStatus(CatalogRef(), Delegate::STATUS_REFRESHED); if (d->delegate) {
d->firePackagesChanged(); d->delegate->refreshComplete();
}
}
bool Root::removeCatalogById(const std::string& aId)
{
CatalogRef cat;
CatalogDict::iterator catIt = d->catalogs.find(aId);
if (catIt == d->catalogs.end()) {
// check the disabled list
CatalogList::iterator j = d->disabledCatalogs.begin();
for (; j != d->disabledCatalogs.end(); ++j) {
if ((*j)->id() == aId) {
break;
} }
} }
if (j == d->disabledCatalogs.end()) {
SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: no catalog with id:" << aId);
return false;
}
cat = *j;
d->disabledCatalogs.erase(j);
} else {
cat = catIt->second;
// drop the reference
d->catalogs.erase(catIt);
}
bool ok = cat->uninstall();
if (!ok) {
SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: catalog :" << aId
<< "failed to uninstall");
}
// notify that a catalog is being removed
d->firePackagesChanged();
return ok;
}
void Root::requestThumbnailData(const std::string& aUrl)
{
MemThumbnailCache::iterator it = d->thumbnailCache.find(aUrl);
if (it == d->thumbnailCache.end()) {
// insert into cache to mark as pending
d->pendingThumbnails.push_front(aUrl);
d->thumbnailCache[aUrl] = std::string();
d->downloadNextPendingThumbnail();
} else if (!it->second.empty()) {
// already loaded, fire data synchronously
d->fireDataForThumbnail(aUrl, it->second);
} else {
// in cache but empty data, still fetching
}
}
InstallRef Root::existingInstallForPackage(PackageRef p) const
{
RootPrivate::InstallCache::const_iterator it =
d->m_installs.find(p);
if (it == d->m_installs.end()) {
// check if it exists on disk, create
SGPath path(p->pathOnDisk());
if (path.exists()) {
// this will add to our cache, and hence, modify m_installs
return Install::createFromPath(path, p->catalog());
}
// insert a null reference into the dictionary, so we don't call
// the pathOnDisk -> exists codepath repeatedley
d->m_installs[p] = InstallRef();
return InstallRef();
}
return it->second;
}
void Root::registerInstall(InstallRef ins)
{
if (!ins.valid()) {
return;
}
d->m_installs[ins->package()] = ins;
}
void Root::unregisterInstall(InstallRef ins)
{
if (!ins .valid()) {
return;
}
d->m_installs.erase(ins->package());
} }
} // of namespace pkg } // of namespace pkg
+7 -38
View File
@@ -62,9 +62,7 @@ public:
void setLocale(const std::string& aLocale); void setLocale(const std::string& aLocale);
void addDelegate(Delegate* aDelegate); void setDelegate(Delegate* aDelegate);
void removeDelegate(Delegate* aDelegate);
std::string getLocale() const; std::string getLocale() const;
@@ -83,16 +81,10 @@ public:
void makeHTTPRequest(HTTP::Request* req); void makeHTTPRequest(HTTP::Request* req);
/** /**
* The catalog XML/property version in use. This is used to make incomaptible * the version string of the root. Catalogs must match this version,
* changes to the package/catalog syntax
*/
int catalogVersion() const;
/**
* the version string of the application. Catalogs must match this version,
* or they will be ignored / rejected. * or they will be ignored / rejected.
*/ */
std::string applicationVersion() const; std::string catalogVersion() const;
/** /**
* refresh catalogs which are more than the maximum age (24 hours by default) * refresh catalogs which are more than the maximum age (24 hours by default)
@@ -100,11 +92,6 @@ public:
*/ */
void refresh(bool aForce = false); void refresh(bool aForce = false);
/**
*
*/
PackageList allPackages() const;
/** /**
* retrieve packages matching a filter. * retrieve packages matching a filter.
* filter consists of required / minimum values, AND-ed together. * filter consists of required / minimum values, AND-ed together.
@@ -122,39 +109,21 @@ public:
CatalogRef getCatalogById(const std::string& aId) const; CatalogRef getCatalogById(const std::string& aId) const;
void scheduleToUpdate(InstallRef aInstall); void scheduleToUpdate(InstallRef aInstall);
/**
* remove a catalog. Will uninstall all packages originating
* from the catalog too.
*/
bool removeCatalogById(const std::string& aId);
/**
* request thumbnail data from the cache / network
*/
void requestThumbnailData(const std::string& aUrl);
bool isInstallQueued(InstallRef aInstall) const;
private: private:
friend class Install; friend class Install;
friend class Catalog; friend class Catalog;
friend class Package;
InstallRef existingInstallForPackage(PackageRef p) const;
void catalogRefreshStatus(CatalogRef aCat, Delegate::StatusCode aReason); void catalogRefreshBegin(CatalogRef aCat);
void catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason);
void startNext(InstallRef aCurrent); void startNext(InstallRef aCurrent);
void startInstall(InstallRef aInstall); void startInstall(InstallRef aInstall);
void installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal); void installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal);
void finishInstall(InstallRef aInstall, Delegate::StatusCode aReason); void finishInstall(InstallRef aInstall);
void cancelDownload(InstallRef aInstall); void failedInstall(InstallRef aInstall, Delegate::FailureCode aReason);
void registerInstall(InstallRef ins);
void unregisterInstall(InstallRef ins);
class ThumbnailDownloader;
class RootPrivate; class RootPrivate;
std::auto_ptr<RootPrivate> d; std::auto_ptr<RootPrivate> d;
}; };
-64
View File
@@ -1,64 +0,0 @@
<?xml version="1.0"?>
<PropertyList>
<id>org.flightgear.test.catalog1</id>
<description>First test catalog</description>
<url>http://download.flightgear.org/catalog1/catalog.xml</url>
<version>8.1.*</version>
<version>8.0.0</version>
<version>8.2.0</version>
<package>
<id>alpha</id>
<name>Alpha package</name>
<revision type="int">8</revision>
<file-size-bytes type="int">1234567</file-size-bytes>
</package>
<package>
<id>c172p</id>
<name>Cessna 172-P</name>
<description>A plane made by Cessna</description>
<revision type="int">42</revision>
<file-size-bytes type="int">34567</file-size-bytes>
<tag>cessna</tag>
<tag>ga</tag>
<tag>piston</tag>
<tag>ifr</tag>
<rating>
<FDM type="int">3</FDM>
<systems type="int">4</systems>
<model type="int">5</model>
<cockpit type="int">4</cockpit>
</rating>
<!-- local dependency -->
<depends>
<id>org.flightgear.test.catalog1.common-sounds</id>
<revision>10</revision>
</depends>
<variant>
<id>c172p-2d-panel</id>
<name>C172 with 2d panel only</name>
</variant>
<variant>
<id>c172p-floats</id>
<name>C172 with floats</name>
</variant>
<variant>
<id>c172p-skis</id>
<name>C172 with skis</name>
</variant>
</package>
<package>
<id>common-sounds</id>
<name>Common sound files for test catalog aircraft</name>
<revision>10</revision>
</package>
</PropertyList>
+1 -2
View File
@@ -158,8 +158,7 @@ SG_MD5Transform(u_int32_t state[4], const u_int8_t block[MD5_BLOCK_LENGTH])
{ {
u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4]; u_int32_t a, b, c, d, in[MD5_BLOCK_LENGTH / 4];
#if ((defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || \ #ifndef WORDS_BIGENDIAN
defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM) )
memcpy(in, block, sizeof(in)); memcpy(in, block, sizeof(in));
#else #else
for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) { for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
+15 -21
View File
@@ -34,28 +34,22 @@ bool keepRunning = true;
class MyDelegate : public pkg::Delegate class MyDelegate : public pkg::Delegate
{ {
public: public:
virtual void catalogRefreshed(pkg::CatalogRef aCatalog, StatusCode aReason) virtual void refreshComplete()
{ {
if (aReason == STATUS_REFRESHED) {
if (aCatalog.ptr() == NULL) {
cout << "refreshed all catalogs" << endl;
} else {
cout << "refreshed catalog " << aCatalog->url() << endl;
}
} else if (aReason == STATUS_IN_PROGRESS) {
cout << "started refresh of " << aCatalog->url() << endl;
} else {
cerr << "failed refresh of " << aCatalog->url() << ":" << aReason << endl;
}
} }
virtual void startInstall(pkg::InstallRef aInstall) virtual void failedRefresh(pkg::Catalog* aCatalog, FailureCode aReason)
{
cerr << "failed refresh of " << aCatalog->description() << ":" << aReason << endl;
}
virtual void startInstall(pkg::Install* aInstall)
{ {
_lastPercent = 999; _lastPercent = 999;
cout << "starting install of " << aInstall->package()->name() << endl; cout << "starting install of " << aInstall->package()->name() << endl;
} }
virtual void installProgress(pkg::InstallRef aInstall, unsigned int bytes, unsigned int total) virtual void installProgress(pkg::Install* aInstall, unsigned int bytes, unsigned int total)
{ {
unsigned int percent = (bytes * 100) / total; unsigned int percent = (bytes * 100) / total;
if (percent == _lastPercent) { if (percent == _lastPercent) {
@@ -66,15 +60,15 @@ public:
cout << percent << "%" << endl; cout << percent << "%" << endl;
} }
virtual void finishInstall(pkg::InstallRef aInstall, StatusCode aReason) virtual void finishInstall(pkg::Install* aInstall)
{ {
if (aReason == STATUS_SUCCESS) {
cout << "done install of " << aInstall->package()->name() << endl; cout << "done install of " << aInstall->package()->name() << endl;
} else {
cerr << "failed install of " << aInstall->package()->name() << endl;
}
} }
virtual void failedInstall(pkg::Install* aInstall, FailureCode aReason)
{
cerr << "failed install of " << aInstall->package()->name() << endl;
}
private: private:
unsigned int _lastPercent; unsigned int _lastPercent;
@@ -125,10 +119,10 @@ int main(int argc, char** argv)
pkg::Root* root = new pkg::Root(Dir::current().path(), ""); pkg::Root* root = new pkg::Root(Dir::current().path(), "");
MyDelegate dlg; MyDelegate dlg;
root->addDelegate(&dlg); root->setDelegate(&dlg);
cout << "Package root is:" << Dir::current().path() << endl; cout << "Package root is:" << Dir::current().path() << endl;
cout << "have " << root->catalogs().size() << " catalog(s)" << endl; cout << "have " << pkg::Catalog::allCatalogs().size() << " catalog(s)" << endl;
root->setHTTPClient(http); root->setHTTPClient(http);
+4 -4
View File
@@ -144,9 +144,9 @@ public:
#undef SG_DEF_ASSIGN_OP #undef SG_DEF_ASSIGN_OP
SGPropertyNode* node(bool aCreate = false) const SGPropertyNode* node() const
{ {
return PropertyObjectBase::node(aCreate); return PropertyObjectBase::node(false);
} }
}; // of template PropertyObject }; // of template PropertyObject
@@ -237,9 +237,9 @@ public:
return (s == value); return (s == value);
} }
SGPropertyNode* node(bool aCreate = false) const SGPropertyNode* node() const
{ {
return PropertyObjectBase::node(aCreate); return PropertyObjectBase::node(false);
} }
private: private:
}; };
+32 -253
View File
@@ -11,6 +11,8 @@
#endif #endif
#include "props.hxx" #include "props.hxx"
#include "PropertyInterpolationMgr.hxx"
#include "vectorPropTemplates.hxx"
#include <algorithm> #include <algorithm>
#include <limits> #include <limits>
@@ -22,30 +24,31 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <boost/algorithm/string/find_iterator.hpp>
#include <boost/algorithm/string/predicate.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/bind.hpp>
#include <boost/functional/hash.hpp>
#include <boost/range.hpp>
#if PROPS_STANDALONE #if PROPS_STANDALONE
# include <iostream> #include <iostream>
using std::cerr;
#else #else
# include <boost/algorithm/string/find_iterator.hpp>
# include <boost/algorithm/string/predicate.hpp>
# include <boost/algorithm/string/classification.hpp>
# include <boost/bind.hpp>
# include <boost/functional/hash.hpp>
# include <boost/range.hpp>
# include <simgear/compiler.h>
# include <simgear/debug/logstream.hxx>
# include "PropertyInterpolationMgr.hxx" #include <simgear/compiler.h>
# include "vectorPropTemplates.hxx" #include <simgear/debug/logstream.hxx>
# if ( _MSC_VER == 1200 ) #if ( _MSC_VER == 1200 )
// MSVC 6 is buggy, and needs something strange here // MSVC 6 is buggy, and needs something strange here
using std::vector<SGPropertyNode_ptr>; using std::vector<SGPropertyNode_ptr>;
using std::vector<SGPropertyChangeListener *>; using std::vector<SGPropertyChangeListener *>;
using std::vector<SGPropertyNode *>; using std::vector<SGPropertyNode *>;
# endif #endif
#endif #endif
#if PROPS_STANDALONE
using std::cerr;
#endif
using std::endl; using std::endl;
using std::find; using std::find;
using std::sort; using std::sort;
@@ -81,14 +84,6 @@ public:
// Local path normalization code. // Local path normalization code.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
#if PROPS_STANDALONE
struct PathComponent
{
string name;
int index;
};
#endif
/** /**
* Parse the name for a path component. * Parse the name for a path component.
* *
@@ -151,149 +146,10 @@ inline bool validateName(const std::string& name)
return false; return false;
if (!isalpha(name[0]) && name[0] != '_') if (!isalpha(name[0]) && name[0] != '_')
return false; return false;
#if PROPS_STANDALONE
std::string is_any_of("_-.");
bool rv = true;
for(unsigned i=1; i<name.length(); ++i) {
if (!isalnum(name[i]) && is_any_of.find(name[i]) == std::string::npos) {
rv = false;
break;
}
}
return rv;
#else
return all(make_iterator_range(name.begin(), name.end()), return all(make_iterator_range(name.begin(), name.end()),
is_alnum() || is_any_of("_-.")); is_alnum() || is_any_of("_-."));
#endif
} }
#if PROPS_STANDALONE
/**
* Parse the name for a path component.
*
* Name: [_a-zA-Z][-._a-zA-Z0-9]*
*/
static inline const string
parse_name (const string &path, int &i)
{
string name = "";
int max = (int)path.size();
if (path[i] == '.') {
i++;
if (i < max && path[i] == '.') {
i++;
name = "..";
} else {
name = ".";
}
if (i < max && path[i] != '/')
throw string("Illegal character after " + name);
}
else if (isalpha(path[i]) || path[i] == '_') {
name += path[i];
i++;
// The rules inside a name are a little
// less restrictive.
while (i < max) {
if (isalpha(path[i]) || isdigit(path[i]) || path[i] == '_' ||
path[i] == '-' || path[i] == '.') {
name += path[i];
} else if (path[i] == '[' || path[i] == '/') {
break;
} else {
throw string("name may contain only ._- and alphanumeric characters");
}
i++;
}
}
else {
if (name.size() == 0)
throw string("name must begin with alpha or '_'");
}
return name;
}
/**
* Parse the optional integer index for a path component.
*
* Index: "[" [0-9]+ "]"
*/
static inline int
parse_index (const string &path, int &i)
{
int index = 0;
if (path[i] != '[')
return 0;
else
i++;
for (int max = (int)path.size(); i < max; i++) {
if (isdigit(path[i])) {
index = (index * 10) + (path[i] - '0');
} else if (path[i] == ']') {
i++;
return index;
} else {
break;
}
}
throw string("unterminated index (looking for ']')");
}
/**
* Parse a single path component.
*
* Component: Name Index?
*/
static inline PathComponent
parse_component (const string &path, int &i)
{
PathComponent component;
component.name = parse_name(path, i);
if (component.name[0] != '.')
component.index = parse_index(path, i);
else
component.index = -1;
return component;
}
/**
* Parse a path into its components.
*/
static void
parse_path (const string &path, vector<PathComponent> &components)
{
int pos = 0;
int max = (int)path.size();
// Check for initial '/'
if (path[pos] == '/') {
PathComponent root;
root.name = "";
root.index = -1;
components.push_back(root);
pos++;
while (pos < max && path[pos] == '/')
pos++;
}
while (pos < max) {
components.push_back(parse_component(path, pos));
while (pos < max && path[pos] == '/')
pos++;
}
}
#endif
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Other static utility functions. // Other static utility functions.
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -326,13 +182,6 @@ static int
find_child (Itr begin, Itr end, int index, const PropertyList& nodes) find_child (Itr begin, Itr end, int index, const PropertyList& nodes)
{ {
size_t nNodes = nodes.size(); size_t nNodes = nodes.size();
#if PROPS_STANDALONE
for (int i = 0; i < nNodes; i++) {
SGPropertyNode * node = nodes[i];
if (node->getIndex() == index && compare_strings(node->getName(), begin))
return i;
}
#else
boost::iterator_range<Itr> name(begin, end); boost::iterator_range<Itr> name(begin, end);
for (size_t i = 0; i < nNodes; i++) { for (size_t i = 0; i < nNodes; i++) {
SGPropertyNode * node = nodes[i]; SGPropertyNode * node = nodes[i];
@@ -342,7 +191,6 @@ find_child (Itr begin, Itr end, int index, const PropertyList& nodes)
if (node->getIndex() == index && boost::equals(node->getName(), name)) if (node->getIndex() == index && boost::equals(node->getName(), name))
return static_cast<int>(i); return static_cast<int>(i);
} }
#endif
return -1; return -1;
} }
@@ -485,52 +333,6 @@ find_node_aux(SGPropertyNode * current, SplitItr& itr, bool create,
// Internal function for parsing property paths. last_index provides // Internal function for parsing property paths. last_index provides
// and index value for the last node name token, if supplied. // and index value for the last node name token, if supplied.
#if PROPS_STANDALONE
static SGPropertyNode *
find_node (SGPropertyNode * current,
const vector<PathComponent> &components,
int position,
bool create)
{
// Run off the end of the list
if (current == 0) {
return 0;
}
// Success! This is the one we want.
else if (position >= (int)components.size()) {
return (current->getAttribute(SGPropertyNode::REMOVED) ? 0 : current);
}
// Empty component means root.
else if (components[position].name == "") {
return find_node(current->getRootNode(), components, position + 1, create);
}
// . means current directory
else if (components[position].name == ".") {
return find_node(current, components, position + 1, create);
}
// .. means parent directory
else if (components[position].name == "..") {
SGPropertyNode * parent = current->getParent();
if (parent == 0)
throw string("Attempt to move past root with '..'");
else
return find_node(parent, components, position + 1, create);
}
// Otherwise, a child name
else {
SGPropertyNode * child =
current->getChild(components[position].name.c_str(),
components[position].index,
create);
return find_node(child, components, position + 1, create);
}
}
#else
template<typename Range> template<typename Range>
SGPropertyNode* SGPropertyNode*
find_node (SGPropertyNode * current, find_node (SGPropertyNode * current,
@@ -549,7 +351,6 @@ find_node (SGPropertyNode * current,
else else
return find_node_aux(current, itr, create, last_index); return find_node_aux(current, itr, create, last_index);
} }
#endif
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
// Private methods from SGPropertyNode (may be inlined for speed). // Private methods from SGPropertyNode (may be inlined for speed).
@@ -810,8 +611,13 @@ SGPropertyNode::make_string () const
void void
SGPropertyNode::trace_write () const SGPropertyNode::trace_write () const
{ {
#if PROPS_STANDALONE
cerr << "TRACE: Write node " << getPath () << ", value \""
<< make_string() << '"' << endl;
#else
SG_LOG(SG_GENERAL, SG_ALERT, "TRACE: Write node " << getPath() SG_LOG(SG_GENERAL, SG_ALERT, "TRACE: Write node " << getPath()
<< ", value \"" << make_string() << '"'); << ", value \"" << make_string() << '"');
#endif
} }
/** /**
@@ -820,8 +626,13 @@ SGPropertyNode::trace_write () const
void void
SGPropertyNode::trace_read () const SGPropertyNode::trace_read () const
{ {
#if PROPS_STANDALONE
cerr << "TRACE: Write node " << getPath () << ", value \""
<< make_string() << '"' << endl;
#else
SG_LOG(SG_GENERAL, SG_ALERT, "TRACE: Read node " << getPath() SG_LOG(SG_GENERAL, SG_ALERT, "TRACE: Read node " << getPath()
<< ", value \"" << make_string() << '"'); << ", value \"" << make_string() << '"');
#endif
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
@@ -975,6 +786,8 @@ SGPropertyNode::alias (SGPropertyNode * target)
return true; return true;
} }
#if PROPS_STANDALONE
#else
if (!target) if (!target)
{ {
SG_LOG(SG_GENERAL, SG_ALERT, SG_LOG(SG_GENERAL, SG_ALERT,
@@ -996,6 +809,7 @@ SGPropertyNode::alias (SGPropertyNode * target)
SG_LOG(SG_GENERAL, SG_ALERT, "Failed to create alias at " << target->getPath() << ". " SG_LOG(SG_GENERAL, SG_ALERT, "Failed to create alias at " << target->getPath() << ". "
"Source " << getPath() << " is a tied property."); "Source " << getPath() << " is a tied property.");
} }
#endif
return false; return false;
} }
@@ -1143,18 +957,11 @@ SGPropertyNode::getChild (const char * name, int index, bool create)
SGPropertyNode * SGPropertyNode *
SGPropertyNode::getChild (const std::string& name, int index, bool create) SGPropertyNode::getChild (const std::string& name, int index, bool create)
{ {
#if PROPS_STANDALONE
const char *n = name.c_str();
int pos = find_child(n, n + strlen(n), index, _children);
if (pos >= 0) {
return _children[pos];
#else
SGPropertyNode* node = getExistingChild(name.begin(), name.end(), index); SGPropertyNode* node = getExistingChild(name.begin(), name.end(), index);
if (node) { if (node) {
return node; return node;
#endif
} else if (create) { } else if (create) {
SGPropertyNode* node = new SGPropertyNode(name, index, this); node = new SGPropertyNode(name, index, this);
_children.push_back(node); _children.push_back(node);
fireChildAdded(node); fireChildAdded(node);
return node; return node;
@@ -1828,14 +1635,12 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
case props::UNSPECIFIED: case props::UNSPECIFIED:
result = set_string(value); result = set_string(value);
break; break;
#if !PROPS_STANDALONE
case props::VEC3D: case props::VEC3D:
result = static_cast<SGRawValue<SGVec3d>*>(_value.val)->setValue(parseString<SGVec3d>(value)); result = static_cast<SGRawValue<SGVec3d>*>(_value.val)->setValue(parseString<SGVec3d>(value));
break; break;
case props::VEC4D: case props::VEC4D:
result = static_cast<SGRawValue<SGVec4d>*>(_value.val)->setValue(parseString<SGVec4d>(value)); result = static_cast<SGRawValue<SGVec4d>*>(_value.val)->setValue(parseString<SGVec4d>(value));
break; break;
#endif
case props::NONE: case props::NONE:
default: default:
break; break;
@@ -1847,7 +1652,6 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#if !PROPS_STANDALONE
bool SGPropertyNode::interpolate( const std::string& type, bool SGPropertyNode::interpolate( const std::string& type,
const SGPropertyNode& target, const SGPropertyNode& target,
double duration, double duration,
@@ -1897,7 +1701,6 @@ simgear::PropertyInterpolationMgr* SGPropertyNode::getInterpolationMgr()
} }
simgear::PropertyInterpolationMgr* SGPropertyNode::_interpolation_mgr = 0; simgear::PropertyInterpolationMgr* SGPropertyNode::_interpolation_mgr = 0;
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
std::ostream& SGPropertyNode::printOn(std::ostream& stream) const std::ostream& SGPropertyNode::printOn(std::ostream& stream) const
@@ -2051,37 +1854,20 @@ SGPropertyNode::getRootNode () const
SGPropertyNode * SGPropertyNode *
SGPropertyNode::getNode (const char * relative_path, bool create) SGPropertyNode::getNode (const char * relative_path, bool create)
{ {
#if PROPS_STANDALONE
vector<PathComponent> components;
parse_path(relative_path, components);
return find_node(this, components, 0, create);
#else
using namespace boost; using namespace boost;
return find_node(this, make_iterator_range(relative_path, relative_path return find_node(this, make_iterator_range(relative_path, relative_path
+ strlen(relative_path)), + strlen(relative_path)),
create); create);
#endif
} }
SGPropertyNode * SGPropertyNode *
SGPropertyNode::getNode (const char * relative_path, int index, bool create) SGPropertyNode::getNode (const char * relative_path, int index, bool create)
{ {
#if PROPS_STANDALONE
vector<PathComponent> components;
parse_path(relative_path, components);
if (components.size() > 0)
components.back().index = index;
return find_node(this, components, 0, create);
#else
using namespace boost; using namespace boost;
return find_node(this, make_iterator_range(relative_path, relative_path return find_node(this, make_iterator_range(relative_path, relative_path
+ strlen(relative_path)), + strlen(relative_path)),
create, index); create, index);
#endif
} }
const SGPropertyNode * const SGPropertyNode *
@@ -2529,7 +2315,6 @@ SGPropertyChangeListener::unregister_property (SGPropertyNode * node)
_properties.erase(it); _properties.erase(it);
} }
#if !PROPS_STANDALONE
template<> template<>
std::ostream& SGRawBase<SGVec3d>::printOn(std::ostream& stream) const std::ostream& SGRawBase<SGVec3d>::printOn(std::ostream& stream) const
{ {
@@ -2566,11 +2351,9 @@ std::ostream& SGRawBase<SGVec4d>::printOn(std::ostream& stream) const
} }
return stream; return stream;
} }
#endif
namespace simgear namespace simgear
{ {
#if !PROPS_STANDALONE
template<> template<>
std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result) std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result)
{ {
@@ -2579,7 +2362,6 @@ std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result)
} }
return stream; return stream;
} }
#endif
namespace namespace
{ {
@@ -2607,12 +2389,10 @@ bool compareNodeValue(const SGPropertyNode& lhs, const SGPropertyNode& rhs)
case props::STRING: case props::STRING:
case props::UNSPECIFIED: case props::UNSPECIFIED:
return !strcmp(lhs.getStringValue(), rhs.getStringValue()); return !strcmp(lhs.getStringValue(), rhs.getStringValue());
#if !PROPS_STANDALONE
case props::VEC3D: case props::VEC3D:
return lhs.getValue<SGVec3d>() == rhs.getValue<SGVec3d>(); return lhs.getValue<SGVec3d>() == rhs.getValue<SGVec3d>();
case props::VEC4D: case props::VEC4D:
return lhs.getValue<SGVec4d>() == rhs.getValue<SGVec4d>(); return lhs.getValue<SGVec4d>() == rhs.getValue<SGVec4d>();
#endif
default: default:
return false; return false;
} }
@@ -2669,10 +2449,10 @@ struct PropertyPlaceLess {
} }
}; };
#if !PROPS_STANDALONE
size_t hash_value(const SGPropertyNode& node) size_t hash_value(const SGPropertyNode& node)
{ {
using namespace boost; using namespace boost;
if (node.nChildren() == 0) { if (node.nChildren() == 0) {
switch (node.getType()) { switch (node.getType()) {
case props::NONE: case props::NONE:
@@ -2723,6 +2503,5 @@ size_t hash_value(const SGPropertyNode& node)
return seed; return seed;
} }
} }
#endif
// end of props.cxx // end of props.cxx
+9 -49
View File
@@ -22,54 +22,24 @@
#include <sstream> #include <sstream>
#include <typeinfo> #include <typeinfo>
#include <simgear/compiler.h> #include <boost/utility.hpp>
#include <boost/type_traits/is_enum.hpp>
#if PROPS_STANDALONE #if PROPS_STANDALONE
// taken from: boost/utility/enable_if.hpp
#ifndef SG_LOG
# define SG_GENERAL 0
# define SG_ALERT 0
# define SG_WARN 1
# define SG_LOG(type, level, message) (type) ? (std::cerr <<message << endl) : (std::cout <<message << endl)
#endif
namespace boost {
template <bool B, class T = void>
struct enable_if_c {
typedef T type;
};
template <class T>
struct enable_if_c<false, T> {};
template <class Cond, class T = void>
struct enable_if : public enable_if_c<Cond::value, T> {};
template <bool B, class T = void>
struct disable_if_c {
typedef T type;
};
template <class T>
struct disable_if_c<true, T> {};
template <class Cond, class T = void>
struct disable_if : public disable_if_c<Cond::value, T> {};
}
#else #else
# include <boost/utility.hpp> #include <simgear/compiler.h>
# include <boost/type_traits/is_enum.hpp> #include <simgear/debug/logstream.hxx>
# include <simgear/debug/logstream.hxx>
# include <simgear/math/SGMathFwd.hxx>
# include <simgear/math/sg_types.hxx>
#endif #endif
#include <simgear/math/SGMathFwd.hxx>
#include <simgear/math/sg_types.hxx>
#include <simgear/structure/SGReferenced.hxx> #include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx> #include <simgear/structure/SGSharedPtr.hxx>
// XXX This whole file should be in the simgear namespace, but I don't // XXX This whole file should be in the simgear namespace, but I don't
// have the guts yet... // have the guts yet...
using namespace std;
namespace simgear namespace simgear
{ {
@@ -1305,7 +1275,6 @@ public:
return ret; return ret;
} }
#if !PROPS_STANDALONE
/** /**
* Interpolate current value to target value within given time. * Interpolate current value to target value within given time.
* *
@@ -1341,7 +1310,6 @@ public:
* Get the interpolation manager * Get the interpolation manager
*/ */
static simgear::PropertyInterpolationMgr* getInterpolationMgr(); static simgear::PropertyInterpolationMgr* getInterpolationMgr();
#endif
/** /**
* Print the value of the property to a stream. * Print the value of the property to a stream.
@@ -1839,11 +1807,7 @@ private:
// Convenience functions for use in templates // Convenience functions for use in templates
template<typename T> template<typename T>
#if PROPS_STANDALONE
T
#else
typename boost::disable_if<boost::is_enum<T>, T>::type typename boost::disable_if<boost::is_enum<T>, T>::type
#endif
getValue(const SGPropertyNode*); getValue(const SGPropertyNode*);
template<> template<>
@@ -1907,11 +1871,7 @@ namespace simgear
/** Extract enum from SGPropertyNode */ /** Extract enum from SGPropertyNode */
template<typename T> template<typename T>
#if PROPS_STANDALONE
inline T
#else
inline typename boost::enable_if<boost::is_enum<T>, T>::type inline typename boost::enable_if<boost::is_enum<T>, T>::type
#endif
getValue(const SGPropertyNode* node) getValue(const SGPropertyNode* node)
{ {
typedef simgear::enum_traits<T> Traits; typedef simgear::enum_traits<T> Traits;
-10
View File
@@ -326,15 +326,9 @@ public:
= GL2Extensions::Get(static_cast<unsigned>(contextId), true); = GL2Extensions::Get(static_cast<unsigned>(contextId), true);
if (!extensions) if (!extensions)
return; return;
#if OSG_VERSION_LESS_THAN(3,3,4)
if (!extensions->isGlslSupported()) if (!extensions->isGlslSupported())
return; return;
value = extensions->getLanguageVersion(); value = extensions->getLanguageVersion();
#else
if (!extensions->isGlslSupported)
return;
value = extensions->glslLanguageVersion;
#endif
} }
}; };
@@ -363,11 +357,7 @@ public:
= GL2Extensions::Get(static_cast<unsigned>(contextId), true); = GL2Extensions::Get(static_cast<unsigned>(contextId), true);
if (!extensions) if (!extensions)
return; return;
#if OSG_VERSION_LESS_THAN(3,3,4)
value = extensions->isGlslSupported(); value = extensions->isGlslSupported();
#else
value = extensions->isGlslSupported;
#endif
} }
}; };
-1
View File
@@ -323,7 +323,6 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
// Random vegetation properties // Random vegetation properties
wood_coverage = props->getDoubleValue("wood-coverage", 0.0); wood_coverage = props->getDoubleValue("wood-coverage", 0.0);
tree_effect = props->getStringValue("tree-effect", "Effects/tree");
tree_height = props->getDoubleValue("tree-height-m", 0.0); tree_height = props->getDoubleValue("tree-height-m", 0.0);
tree_width = props->getDoubleValue("tree-width-m", 0.0); tree_width = props->getDoubleValue("tree-width-m", 0.0);
tree_range = props->getDoubleValue("tree-range-m", 0.0); tree_range = props->getDoubleValue("tree-range-m", 0.0);
-11
View File
@@ -274,14 +274,6 @@ public:
*/ */
inline std::string get_tree_texture () const { return tree_texture; } inline std::string get_tree_texture () const { return tree_texture; }
/**
* Get the effect file name to use for trees
*
* @return the effect to use for this set of trees.
*/
inline std::string get_tree_effect () const { return tree_effect; }
/** /**
* Get the cosine of the maximum tree density slope angle. We * Get the cosine of the maximum tree density slope angle. We
* use the cosine as it can be compared directly to the z component * use the cosine as it can be compared directly to the z component
@@ -485,9 +477,6 @@ private:
// Tree texture, typically a strip of applicable tree textures // Tree texture, typically a strip of applicable tree textures
std::string tree_texture; std::string tree_texture;
// Tree effect to be used for a particular material
std::string tree_effect;
// Object mask, a simple RGB texture used as a mask when placing // Object mask, a simple RGB texture used as a mask when placing
// random vegetation, objects and buildings // random vegetation, objects and buildings
std::vector<Texture2DRef> _masks; std::vector<Texture2DRef> _masks;
+2 -2
View File
@@ -201,7 +201,7 @@ SGMaterialCache *SGMaterialLib::generateMatCache(SGGeod center)
// Destructor // Destructor
SGMaterialLib::~SGMaterialLib ( void ) { SGMaterialLib::~SGMaterialLib ( void ) {
SG_LOG( SG_TERRAIN, SG_DEBUG, "SGMaterialLib::~SGMaterialLib() size=" << matlib.size()); SG_LOG( SG_GENERAL, SG_INFO, "SGMaterialLib::~SGMaterialLib() size=" << matlib.size());
} }
const SGMaterial *SGMaterialLib::findMaterial(const osg::Geode* geode) const SGMaterial *SGMaterialLib::findMaterial(const osg::Geode* geode)
@@ -244,5 +244,5 @@ SGMaterial *SGMaterialCache::find(const string& material) const
// Destructor // Destructor
SGMaterialCache::~SGMaterialCache ( void ) { SGMaterialCache::~SGMaterialCache ( void ) {
SG_LOG( SG_TERRAIN, SG_DEBUG, "SGMaterialCache::~SGMaterialCache() size=" << cache.size()); SG_LOG( SG_GENERAL, SG_INFO, "SGMaterialCache::~SGMaterialCache() size=" << cache.size());
} }
+1 -7
View File
@@ -364,8 +364,6 @@ public:
if (_textureProp) { if (_textureProp) {
std::string textureName = _textureProp->getStringValue(); std::string textureName = _textureProp->getStringValue();
if (_textureName != textureName) { if (_textureName != textureName) {
_textureName = textureName;
while (stateSet->getTextureAttribute(0, while (stateSet->getTextureAttribute(0,
osg::StateAttribute::TEXTURE)) { osg::StateAttribute::TEXTURE)) {
stateSet->removeTextureAttribute(0, osg::StateAttribute::TEXTURE); stateSet->removeTextureAttribute(0, osg::StateAttribute::TEXTURE);
@@ -379,11 +377,7 @@ public:
osg::StateAttribute::OVERRIDE); osg::StateAttribute::OVERRIDE);
stateSet->setTextureMode(0, GL_TEXTURE_2D, stateSet->setTextureMode(0, GL_TEXTURE_2D,
osg::StateAttribute::ON); osg::StateAttribute::ON);
} _textureName = textureName;
} else {
SG_LOG(SG_IO, SG_WARN, "texture animation: requested texture : " << textureName << " not found. Searched paths:" );
for( osgDB::FilePathList::iterator it = _texturePathList.begin(); it != _texturePathList.end(); ++it ) {
SG_LOG(SG_IO, SG_WARN, " - " << *it );
} }
} }
} }
-4
View File
@@ -54,7 +54,6 @@ SGModelLib::panel_func SGModelLib::static_panelFunc = NULL;
void SGModelLib::init(const string &root_dir, SGPropertyNode* root) void SGModelLib::init(const string &root_dir, SGPropertyNode* root)
{ {
osgDB::Registry::instance()->getDataFilePathList().push_front(root_dir); osgDB::Registry::instance()->getDataFilePathList().push_front(root_dir);
osgDB::Registry::instance()->getOptions()->getDatabasePathList().push_front(root_dir);
static_propRoot = root; static_propRoot = root;
} }
@@ -115,7 +114,6 @@ SGModelLib::loadModel(const string &path,
{ {
osg::ref_ptr<SGReaderWriterOptions> opt; osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions()); opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
opt->getDatabasePathList().push_front( osgDB::getFilePath(path) );
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get()); opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data); opt->setModelData(data);
@@ -138,10 +136,8 @@ SGModelLib::loadDeferredModel(const string &path, SGPropertyNode *prop_root,
proxyNode->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER); proxyNode->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
proxyNode->setFileName(0, path); proxyNode->setFileName(0, path);
osg::ref_ptr<SGReaderWriterOptions> opt; osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions()); opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
opt->getDatabasePathList().push_front( osgDB::getFilePath(path) );
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get()); opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data); opt->setModelData(data);
opt->setLoadPanel(static_panelFunc); opt->setLoadPanel(static_panelFunc);
@@ -128,11 +128,7 @@ void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
sortData.frameSorted = frameNumber; sortData.frameSorted = frameNumber;
} }
#if OSG_VERSION_LESS_THAN(3,3,4)
const Extensions* extensions = getExtensions(state.getContextID(),true); const Extensions* extensions = getExtensions(state.getContextID(),true);
#else
const GLExtensions* extensions = GLExtensions::Get(state.getContextID(), true);
#endif
GLfloat ua1[3] = { (GLfloat) alpha_factor, GLfloat ua1[3] = { (GLfloat) alpha_factor,
(GLfloat) shade_factor, (GLfloat) shade_factor,
(GLfloat) cloud_height }; (GLfloat) cloud_height };
+7 -57
View File
@@ -216,46 +216,6 @@ SGSun::build( SGPath path, double sun_size, SGPropertyNode *property_tree_Node )
sun_transform->addChild( geode ); sun_transform->addChild( geode );
// set up the brilliance state
geode = new osg::Geode;
stateSet = geode->getOrCreateStateSet();
stateSet->setRenderBinDetails(-9, "RenderBin");
texture = SGLoadTexture2D("brilliance.png", options.get());
stateSet->setTextureAttributeAndModes(0, texture);
// Build ssg structure
brilliance_cl = new osg::Vec4Array;
brilliance_cl->push_back(osg::Vec4(1, 1, 1, 1));
double brilliance_size = sun_size * 12.0;
osg::Vec3Array* brilliance_vl = new osg::Vec3Array;
brilliance_vl->push_back(osg::Vec3(-brilliance_size, 0, -brilliance_size));
brilliance_vl->push_back(osg::Vec3(brilliance_size, 0, -brilliance_size));
brilliance_vl->push_back(osg::Vec3(-brilliance_size, 0, brilliance_size));
brilliance_vl->push_back(osg::Vec3(brilliance_size, 0, brilliance_size));
osg::Vec2Array* brilliance_tl = new osg::Vec2Array;
brilliance_tl->push_back(osg::Vec2(0, 0));
brilliance_tl->push_back(osg::Vec2(1, 0));
brilliance_tl->push_back(osg::Vec2(0, 1));
brilliance_tl->push_back(osg::Vec2(1, 1));
geometry = new osg::Geometry;
geometry->setUseDisplayList(false);
geometry->setVertexArray(brilliance_vl);
geometry->setColorArray(brilliance_cl.get(), osg::Array::BIND_OVERALL);
geometry->setNormalBinding(osg::Geometry::BIND_OFF);
geometry->setTexCoordArray(0, brilliance_tl, osg::Array::BIND_PER_VERTEX);
geometry->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLE_STRIP, 0, 4));
geode->addDrawable(geometry);
sun_transform->addChild( geode );
// force a repaint of the sun colors with arbitrary defaults // force a repaint of the sun colors with arbitrary defaults
repaint( 0.0, 1.0 ); repaint( 0.0, 1.0 );
@@ -302,7 +262,7 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
} }
// ok, now let's go and generate the sun and scene color // ok, now let's go and generate the sun and scene color
osg::Vec4 i_halo_color, o_halo_color, scene_color, sun_color, brilliance_color; osg::Vec4 i_halo_color, o_halo_color, scene_color, sun_color;
// Some comments: // Some comments:
// * When the sunangle changes, light has to travel a longer // * When the sunangle changes, light has to travel a longer
@@ -376,29 +336,16 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
if (o_halo_color[3] > 1) o_halo_color[3] = 1; if (o_halo_color[3] > 1) o_halo_color[3] = 1;
if (o_halo_color[3] < 0) o_halo_color[3] = 0; if (o_halo_color[3] < 0) o_halo_color[3] = 0;
brilliance_color[0] = i_halo_color[0];
brilliance_color[1] = i_halo_color[1];
brilliance_color[2] = i_halo_color[2];
double norm = (i_halo_color[0] * i_halo_color[0] + i_halo_color[1] * i_halo_color[1] + i_halo_color[2] * i_halo_color[2])/1.732;
brilliance_color[3] = pow(norm, 6.0);
if (brilliance_color[3] < 0.0) {brilliance_color[3] = 0.0;}
gamma_correct_rgb( i_halo_color._v ); gamma_correct_rgb( i_halo_color._v );
gamma_correct_rgb( o_halo_color._v ); gamma_correct_rgb( o_halo_color._v );
gamma_correct_rgb( scene_color._v ); gamma_correct_rgb( scene_color._v );
gamma_correct_rgb( sun_color._v ); gamma_correct_rgb( sun_color._v );
gamma_correct_rgb( brilliance_color._v );
if (sun_angle >91.0 * 3.1415/180.0 + horizon_angle) if (sun_angle >91.0 * 3.1415/180.0 + horizon_angle)
{ {
sun_color[3] = 0; sun_color[3] = 0;
o_halo_color[3]=0; o_halo_color[3]=0;
i_halo_color[3]=0; i_halo_color[3]=0;
brilliance_color[3]=0;
} }
(*sun_cl)[0] = sun_color; (*sun_cl)[0] = sun_color;
@@ -409,8 +356,6 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
ihalo_cl->dirty(); ihalo_cl->dirty();
(*ohalo_cl)[0] = o_halo_color; (*ohalo_cl)[0] = o_halo_color;
ohalo_cl->dirty(); ohalo_cl->dirty();
(*brilliance_cl)[0] = brilliance_color;
brilliance_cl->dirty();
} }
return true; return true;
@@ -427,14 +372,19 @@ bool SGSun::reposition( double rightAscension, double declination,
{ {
// GST - GMT sidereal time // GST - GMT sidereal time
osg::Matrix T2, RA, DEC; osg::Matrix T2, RA, DEC;
// xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0), // xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0),
// 0.0, 0.0, 1.0); // 0.0, 0.0, 1.0);
RA.makeRotate(rightAscension - 90*SGD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, 1)); RA.makeRotate(rightAscension - 90*SGD_DEGREES_TO_RADIANS, osg::Vec3(0, 0, 1));
// xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0); // xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0);
DEC.makeRotate(declination, osg::Vec3(1, 0, 0)); DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
// xglTranslatef(0,sun_dist); // xglTranslatef(0,sun_dist);
T2.makeTranslate(osg::Vec3(0, sun_dist, 0)); T2.makeTranslate(osg::Vec3(0, sun_dist, 0));
sun_transform->setMatrix(T2*DEC*RA); sun_transform->setMatrix(T2*DEC*RA);
// Suncolor related things: // Suncolor related things:
if ( prev_sun_angle != sun_angle ) { if ( prev_sun_angle != sun_angle ) {
if ( sun_angle == 0 ) sun_angle = 0.1; if ( sun_angle == 0 ) sun_angle = 0.1;
@@ -462,7 +412,7 @@ bool SGSun::reposition( double rightAscension, double declination,
if ( alt_half < 0.0 ) alt_half = 0.0; if ( alt_half < 0.0 ) alt_half = 0.0;
//angle at which the sun is visible below the horizon //angle at which the sun is visible below the horizon
horizon_angle = acos(min(r_earth/position_radius, 1.0)); horizon_angle = acos(r_earth/position_radius);
// Push the data to the property tree, so it can be used in the enviromental code // Push the data to the property tree, so it can be used in the enviromental code
if ( env_node ){ if ( env_node ){
-1
View File
@@ -45,7 +45,6 @@ class SGSun : public SGReferenced {
osg::ref_ptr<osg::Vec4Array> scene_cl; osg::ref_ptr<osg::Vec4Array> scene_cl;
osg::ref_ptr<osg::Vec4Array> ihalo_cl; osg::ref_ptr<osg::Vec4Array> ihalo_cl;
osg::ref_ptr<osg::Vec4Array> ohalo_cl; osg::ref_ptr<osg::Vec4Array> ohalo_cl;
osg::ref_ptr<osg::Vec4Array> brilliance_cl;
double visibility; double visibility;
double prev_sun_angle; double prev_sun_angle;
+35 -67
View File
@@ -44,7 +44,6 @@
#include <simgear/misc/sgstream.hxx> #include <simgear/misc/sgstream.hxx>
#include <simgear/scene/util/OptionsReadFileCallback.hxx> #include <simgear/scene/util/OptionsReadFileCallback.hxx>
#include <simgear/scene/util/OsgMath.hxx> #include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/QuadTreeBuilder.hxx>
#include <simgear/scene/util/RenderConstants.hxx> #include <simgear/scene/util/RenderConstants.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx> #include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/scene/tgdb/apt_signs.hxx> #include <simgear/scene/tgdb/apt_signs.hxx>
@@ -114,79 +113,48 @@ struct ReaderWriterSTG::_ModelBin {
}; };
class DelayLoadReadFileCallback : public OptionsReadFileCallback { class DelayLoadReadFileCallback : public OptionsReadFileCallback {
private:
// QuadTreeBuilder for structuring static objects
struct MakeQuadLeaf {
osg::LOD* operator() () const { return new osg::LOD; }
};
struct AddModelLOD {
void operator() (osg::LOD* leaf, _ObjectStatic o) const
{
osg::ref_ptr<osg::Node> node;
if (o._proxy) {
osg::ref_ptr<osg::ProxyNode> proxy = new osg::ProxyNode;
proxy->setName("proxyNode");
proxy->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
proxy->setFileName(0, o._name);
proxy->setDatabaseOptions(o._options.get());
// Give the node some values so the Quadtree builder has
// a BoundingBox to work with prior to the model being loaded.
proxy->setCenter(osg::Vec3f(0.0f,0.0f,0.0f));
proxy->setRadius(10);
proxy->setCenterMode(osg::ProxyNode::UNION_OF_BOUNDING_SPHERE_AND_USER_DEFINED);
node = proxy;
} else {
node = osgDB::readRefNodeFile(o._name, o._options.get());
if (!node.valid()) {
SG_LOG(SG_TERRAIN, SG_ALERT, o._errorLocation << ": Failed to load "
<< o._token << " '" << o._name << "'");
return;
}
}
if (SGPath(o._name).lower_extension() == "ac")
node->setNodeMask(~simgear::MODELLIGHT_BIT);
osg::Matrix matrix;
matrix = makeZUpFrame(SGGeod::fromDegM(o._lon, o._lat, o._elev));
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(o._hdg), osg::Vec3(0, 0, 1)));
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(o._pitch), osg::Vec3(0, 1, 0)));
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(o._roll), osg::Vec3(1, 0, 0)));
osg::MatrixTransform* matrixTransform;
matrixTransform = new osg::MatrixTransform(matrix);
matrixTransform->setName("rotateStaticObject");
matrixTransform->setDataVariance(osg::Object::STATIC);
matrixTransform->addChild(node.get());
leaf->addChild(matrixTransform, 0, 20000); //TODO: Make configurable?
}
};
struct GetModelLODCoord {
GetModelLODCoord() {}
GetModelLODCoord(const GetModelLODCoord& rhs)
{}
osg::Vec3 operator() (const _ObjectStatic& o) const
{
SGVec3d coord;
SGGeodesy::SGGeodToCart(SGGeod::fromDegM(o._lon, o._lat, o._elev), coord);
return toOsg(coord);
}
};
typedef QuadTreeBuilder<osg::LOD*, _ObjectStatic, MakeQuadLeaf, AddModelLOD,
GetModelLODCoord> STGObjectsQuadtree;
public: public:
virtual osgDB::ReaderWriter::ReadResult virtual osgDB::ReaderWriter::ReadResult
readNode(const std::string&, const osgDB::Options*) readNode(const std::string&, const osgDB::Options*)
{ {
STGObjectsQuadtree quadtree((GetModelLODCoord()), (AddModelLOD())); osg::ref_ptr<osg::Group> group = new osg::Group;
quadtree.buildQuadTree(_objectStaticList.begin(), _objectStaticList.end());
osg::ref_ptr<osg::Group> group = quadtree.getRoot();
group->setName("STG-group-A"); group->setName("STG-group-A");
group->setDataVariance(osg::Object::STATIC); group->setDataVariance(osg::Object::STATIC);
for (std::list<_ObjectStatic>::iterator i = _objectStaticList.begin(); i != _objectStaticList.end(); ++i) {
osg::ref_ptr<osg::Node> node;
if (i->_proxy) {
osg::ref_ptr<osg::ProxyNode> proxy = new osg::ProxyNode;
proxy->setName("proxyNode");
proxy->setLoadingExternalReferenceMode(osg::ProxyNode::DEFER_LOADING_TO_DATABASE_PAGER);
proxy->setFileName(0, i->_name);
proxy->setDatabaseOptions(i->_options.get());
node = proxy;
} else {
node = osgDB::readRefNodeFile(i->_name, i->_options.get());
if (!node.valid()) {
SG_LOG(SG_TERRAIN, SG_ALERT, i->_errorLocation << ": Failed to load "
<< i->_token << " '" << i->_name << "'");
continue;
}
}
if (SGPath(i->_name).lower_extension() == "ac")
node->setNodeMask(~simgear::MODELLIGHT_BIT);
osg::Matrix matrix;
matrix = makeZUpFrame(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev));
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_hdg), osg::Vec3(0, 0, 1)));
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_pitch), osg::Vec3(0, 1, 0)));
matrix.preMultRotate(osg::Quat(SGMiscd::deg2rad(i->_roll), osg::Vec3(1, 0, 0)));
osg::MatrixTransform* matrixTransform;
matrixTransform = new osg::MatrixTransform(matrix);
matrixTransform->setName("positionStaticObject");
matrixTransform->setDataVariance(osg::Object::STATIC);
matrixTransform->addChild(node.get());
group->addChild(matrixTransform);
}
simgear::AirportSignBuilder signBuilder(_options->getMaterialLib(), _bucket.get_center()); simgear::AirportSignBuilder signBuilder(_options->getMaterialLib(), _bucket.get_center());
for (std::list<_Sign>::iterator i = _signList.begin(); i != _signList.end(); ++i) for (std::list<_Sign>::iterator i = _signList.begin(); i != _signList.end(); ++i)
signBuilder.addSign(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev), i->_hdg, i->_name, i->_size); signBuilder.addSign(SGGeod::fromDegM(i->_lon, i->_lat, i->_elev), i->_hdg, i->_name, i->_size);
+5 -5
View File
@@ -386,10 +386,10 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
int row = ((int) (mt_rand(&seed) * 1000)) % 5; int row = ((int) (mt_rand(&seed) * 1000)) % 5;
float base_y = (float) row * 16.0 * 3.0 / 1024.0; float base_y = (float) row * 16.0 * 3.0 / 1024.0;
float top_y = base_y + 16.0 * (float) building.floors / 1024.0; float top_y = base_y + 16.0 * (float) building.floors / 1024.0;
float left_x = 32.0 / 1024.0 * SGMisc<double>::round((float)building.width / 6.0f); float left_x = 32.0 / 1024.0 * round((float) building.width / 6.0f);
float right_x = 0.0f; float right_x = 0.0f;
float front_x = 384.0/1024.0; float front_x = 384.0/1024.0;
float back_x = 384.0 / 1024.0 + 32.0 / 1024.0 * SGMisc<double>::round((float)building.depth / 6.0f); float back_x = 384.0/1024.0 + 32.0 / 1024.0 * round((float) building.depth/ 6.0f);
// BASEMENT - uses the baseline texture // BASEMENT - uses the baseline texture
for (unsigned int i = 0; i < 16; i++) { for (unsigned int i = 0; i < 16; i++) {
@@ -424,7 +424,7 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
if (building.pitched) { if (building.pitched) {
// Use the entire height of the roof texture // Use the entire height of the roof texture
top_y = base_y + 16.0 * 3.0 / 1024.0; top_y = base_y + 16.0 * 3.0 / 1024.0;
left_x = 512 / 1024.0 + 32.0 / 1024.0 * SGMisc<double>::round(building.width / 6.0f); left_x = 512/1024.0 + 32.0 / 1024.0 * round(building.width / 6.0f);
right_x = 512/1024.0; right_x = 512/1024.0;
front_x = 480.0/1024.0; front_x = 480.0/1024.0;
back_x = 512.0/1024.0; back_x = 512.0/1024.0;
@@ -475,7 +475,7 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
int column = ((int) (mt_rand(&seed) * 1000)) % 5; int column = ((int) (mt_rand(&seed) * 1000)) % 5;
float base_y = 288 / 1024.0; float base_y = 288 / 1024.0;
float top_y = base_y + 16.0 * (float) building.floors / 1024.0; float top_y = base_y + 16.0 * (float) building.floors / 1024.0;
float left_x = column * 192.0 / 1024.0 + 32.0 / 1024.0 * SGMisc<double>::round((float)building.width / 10.0f); float left_x = column * 192.0 /1024.0 + 32.0 / 1024.0 * round((float) building.width / 10.0f);
float right_x = column * 192.0 /1024.0; float right_x = column * 192.0 /1024.0;
// BASEMENT - uses the baseline texture // BASEMENT - uses the baseline texture
@@ -560,7 +560,7 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
int column = ((int) (mt_rand(&seed) * 1000)) % 8; int column = ((int) (mt_rand(&seed) * 1000)) % 8;
float base_y = 576 / 1024.0; float base_y = 576 / 1024.0;
float top_y = base_y + 16.0 * (float) building.floors / 1024.0; float top_y = base_y + 16.0 * (float) building.floors / 1024.0;
float left_x = column * 128.0 / 1024.0 + 32.0 / 1024.0 * SGMisc<double>::round((float)building.width / 20.0f); float left_x = column * 128.0 /1024.0 + 32.0 / 1024.0 * round((float) building.width / 20.0f);
float right_x = column * 128.0 /1024.0; float right_x = column * 128.0 /1024.0;
// BASEMENT - uses the baseline texture // BASEMENT - uses the baseline texture
+1 -4
View File
@@ -291,8 +291,7 @@ public:
float vegetation_density, float vegetation_density,
float cos_max_density_angle, float cos_max_density_angle,
float cos_zero_density_angle, float cos_zero_density_angle,
std::vector<SGVec3f>& points, std::vector<SGVec3f>& points)
std::vector<SGVec3f>& normals)
{ {
if ( !geometries.empty() ) { if ( !geometries.empty() ) {
const osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometries[0]->getVertexArray()); const osg::Vec3Array* vertices = dynamic_cast<osg::Vec3Array*>(geometries[0]->getVertexArray());
@@ -367,11 +366,9 @@ public:
if (mt_rand(&seed) < img->getColor(x, y).g()) { if (mt_rand(&seed) < img->getColor(x, y).g()) {
// The red channel contains the rotation for this object // The red channel contains the rotation for this object
points.push_back(randomPoint); points.push_back(randomPoint);
normals.push_back(normalize(normal));
} }
} else { } else {
points.push_back(randomPoint); points.push_back(randomPoint);
normals.push_back(normalize(normal));
} }
} }
} }
+5 -9
View File
@@ -28,7 +28,6 @@
#include <osg/Geometry> #include <osg/Geometry>
#include <osg/PrimitiveSet> #include <osg/PrimitiveSet>
#include <osg/Texture2D> #include <osg/Texture2D>
#include <osg/ref_ptr>
#include <stdio.h> #include <stdio.h>
#include <simgear/math/sg_random.h> #include <simgear/math/sg_random.h>
@@ -123,16 +122,16 @@ public:
osg::DrawElements* getDrawElements() osg::DrawElements* getDrawElements()
{ {
if (count > 65535) { if (count > 65535) {
_ushortElements = 0; free (_ushortElements);
return _uintElements; return _uintElements;
} else { } else {
_uintElements = 0; free (_uintElements);
return _ushortElements; return _ushortElements;
} }
} }
protected: protected:
osg::ref_ptr<osg::DrawElementsUShort> _ushortElements; osg::DrawElementsUShort* _ushortElements;
osg::ref_ptr<osg::DrawElementsUInt> _uintElements; osg::DrawElementsUInt* _uintElements;
unsigned count; unsigned count;
}; };
@@ -216,8 +215,7 @@ public:
float vegetation_density, float vegetation_density,
float cos_max_density_angle, float cos_max_density_angle,
float cos_zero_density_angle, float cos_zero_density_angle,
std::vector<SGVec3f>& points, std::vector<SGVec3f>& points)
std::vector<SGVec3f>& normals)
{ {
unsigned num = getNumTriangles(); unsigned num = getNumTriangles();
for (unsigned i = 0; i < num; ++i) { for (unsigned i = 0; i < num; ++i) {
@@ -283,11 +281,9 @@ public:
if (mt_rand(&seed) < img->getColor(x, y).g()) { if (mt_rand(&seed) < img->getColor(x, y).g()) {
// The red channel contains the rotation for this object // The red channel contains the rotation for this object
points.push_back(randomPoint); points.push_back(randomPoint);
normals.push_back(normalize(normal));
} }
} else { } else {
points.push_back(randomPoint); points.push_back(randomPoint);
normals.push_back(normalize(normal));
} }
} }
} }
+11 -12
View File
@@ -97,7 +97,7 @@ public:
virtual ~SGTileDetailsCallback() virtual ~SGTileDetailsCallback()
{ {
num_tdcb--; num_tdcb--;
SG_LOG( SG_TERRAIN, SG_DEBUG, "SGTileDetailsCallback::~SGTileDetailsCallback() num cbs left " << num_tdcb ); SG_LOG( SG_GENERAL, SG_INFO, "SGTileDetailsCallback::~SGTileDetailsCallback() num cbs left " << num_tdcb );
} }
virtual osgDB::ReaderWriter::ReadResult readNode( virtual osgDB::ReaderWriter::ReadResult readNode(
@@ -723,7 +723,6 @@ public:
BOOST_FOREACH(bin, randomForest) BOOST_FOREACH(bin, randomForest)
{ {
if ((bin->texture == mat->get_tree_texture() ) && if ((bin->texture == mat->get_tree_texture() ) &&
(bin->teffect == mat->get_tree_effect() ) &&
(bin->texture_varieties == mat->get_tree_varieties()) && (bin->texture_varieties == mat->get_tree_varieties()) &&
(bin->range == mat->get_tree_range() ) && (bin->range == mat->get_tree_range() ) &&
(bin->width == mat->get_tree_width() ) && (bin->width == mat->get_tree_width() ) &&
@@ -736,9 +735,7 @@ public:
if (!found) { if (!found) {
bin = new TreeBin(); bin = new TreeBin();
bin->texture = mat->get_tree_texture(); bin->texture = mat->get_tree_texture();
SG_LOG(SG_TERRAIN, SG_DEBUG, "Tree texture " << bin->texture); SG_LOG(SG_INPUT, SG_DEBUG, "Tree texture " << bin->texture);
bin->teffect = mat->get_tree_effect();
SG_LOG(SG_TERRAIN, SG_DEBUG, "Tree effect " << bin->teffect);
bin->range = mat->get_tree_range(); bin->range = mat->get_tree_range();
bin->width = mat->get_tree_width(); bin->width = mat->get_tree_width();
bin->height = mat->get_tree_height(); bin->height = mat->get_tree_height();
@@ -747,19 +744,16 @@ public:
} }
std::vector<SGVec3f> randomPoints; std::vector<SGVec3f> randomPoints;
std::vector<SGVec3f> randomPointNormals;
matTris[i].addRandomTreePoints(wood_coverage, matTris[i].addRandomTreePoints(wood_coverage,
mat->get_one_object_mask(matTris[i].getTextureIndex()), mat->get_one_object_mask(matTris[i].getTextureIndex()),
vegetation_density, vegetation_density,
mat->get_cos_tree_max_density_slope_angle(), mat->get_cos_tree_max_density_slope_angle(),
mat->get_cos_tree_zero_density_slope_angle(), mat->get_cos_tree_zero_density_slope_angle(),
randomPoints, randomPoints);
randomPointNormals);
std::vector<SGVec3f>::iterator k; std::vector<SGVec3f>::iterator k;
std::vector<SGVec3f>::iterator j; for (k = randomPoints.begin(); k != randomPoints.end(); ++k) {
for (k = randomPoints.begin(), j = randomPointNormals.begin(); k != randomPoints.end(); ++k, ++j) { bin->insert(*k);
bin->insert(*k, *j);
} }
} }
} }
@@ -789,6 +783,11 @@ public:
float coverage = mat->get_light_coverage(); float coverage = mat->get_light_coverage();
if (coverage <= 0) if (coverage <= 0)
continue; continue;
if (coverage < 10000.0) {
SG_LOG(SG_INPUT, SG_ALERT, "Light coverage is "
<< coverage << ", pushing up to 10000");
coverage = 10000;
}
int texIndex = matTris[i].getTextureIndex(); int texIndex = matTris[i].getTextureIndex();
@@ -872,7 +871,7 @@ public:
lightGroup->addChild(groundLights2); lightGroup->addChild(groundLights2);
} }
if (! vasiLights.empty()) { if (vasiLights.empty()) {
EffectGeode* vasiGeode = new EffectGeode; EffectGeode* vasiGeode = new EffectGeode;
Effect* vasiEffect = getLightEffect(24, osg::Vec3(1, 0.0001, 0.000001), 1, 24, true, _options); Effect* vasiEffect = getLightEffect(24, osg::Vec3(1, 0.0001, 0.000001), 1, 24, true, _options);
vasiGeode->setEffect(vasiEffect); vasiGeode->setEffect(vasiEffect);
-4
View File
@@ -47,11 +47,7 @@ void ShaderGeometry::addObject(const Vec3& position, float scale,
void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const void ShaderGeometry::drawImplementation(osg::RenderInfo& renderInfo) const
{ {
State& state = *renderInfo.getState(); State& state = *renderInfo.getState();
#if OSG_VERSION_LESS_THAN(3,3,4)
const Extensions* extensions = getExtensions(state.getContextID(), true); const Extensions* extensions = getExtensions(state.getContextID(), true);
#else
const GLExtensions* extensions = GLExtensions::Get(state.getContextID(), true);
#endif
Vec4Array::const_iterator citer = _posScaleArray->begin(); Vec4Array::const_iterator citer = _posScaleArray->begin();
Vec4Array::const_iterator cend = _posScaleArray->end(); Vec4Array::const_iterator cend = _posScaleArray->end();
FloatArray::const_iterator viter = _vertexAttribArray->begin(); FloatArray::const_iterator viter = _vertexAttribArray->begin();
+7 -45
View File
@@ -49,7 +49,6 @@
#include <simgear/scene/util/QuadTreeBuilder.hxx> #include <simgear/scene/util/QuadTreeBuilder.hxx>
#include <simgear/scene/util/RenderConstants.hxx> #include <simgear/scene/util/RenderConstants.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx> #include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/structure/OSGUtils.hxx> #include <simgear/structure/OSGUtils.hxx>
#include "ShaderGeometry.hxx" #include "ShaderGeometry.hxx"
@@ -63,9 +62,6 @@ using namespace osg;
namespace simgear namespace simgear
{ {
bool use_tree_shadows;
bool use_tree_normals;
// Tree instance scheme: // Tree instance scheme:
// vertex - local position of quad vertex. // vertex - local position of quad vertex.
// normal - x y scaling, z number of varieties // normal - x y scaling, z number of varieties
@@ -168,24 +164,15 @@ Geometry* createTreeGeometry(float width, float height, int varieties)
// Positions // Positions
quadGeom->setColorArray(new Vec3Array); quadGeom->setColorArray(new Vec3Array);
quadGeom->setColorBinding(Geometry::BIND_PER_VERTEX); quadGeom->setColorBinding(Geometry::BIND_PER_VERTEX);
// Normals FloatArray* rotation = new FloatArray(2);
if (use_tree_shadows || use_tree_normals)
{
quadGeom->setSecondaryColorArray(new Vec3Array);
quadGeom->setSecondaryColorBinding(Geometry::BIND_PER_VERTEX);
}
FloatArray* rotation = new FloatArray(3);
(*rotation)[0] = 0.0; (*rotation)[0] = 0.0;
(*rotation)[1] = PI_2; (*rotation)[1] = PI_2;
if (use_tree_shadows) {(*rotation)[2] = -1.0;}
quadGeom->setFogCoordArray(rotation); quadGeom->setFogCoordArray(rotation);
quadGeom->setFogCoordBinding(Geometry::BIND_PER_PRIMITIVE_SET); quadGeom->setFogCoordBinding(Geometry::BIND_PER_PRIMITIVE_SET);
// The primitive sets render the same geometry, but the second // The primitive sets render the same geometry, but the second
// will rotated 90 degrees by the vertex shader, which uses the // will rotated 90 degrees by the vertex shader, which uses the
// fog coordinate as a rotation. // fog coordinate as a rotation.
int imax = 2; for (int i = 0; i < 2; ++i)
if (use_tree_shadows) {imax = 3;}
for (int i = 0; i < imax; ++i)
quadGeom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS)); quadGeom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS));
return quadGeom; return quadGeom;
} }
@@ -197,17 +184,13 @@ EffectGeode* createTreeGeode(float width, float height, int varieties)
return result; return result;
} }
void addTreeToLeafGeode(Geode* geode, const SGVec3f& p, const SGVec3f& t) void addTreeToLeafGeode(Geode* geode, const SGVec3f& p)
{ {
Vec3 pos = toOsg(p); Vec3 pos = toOsg(p);
Vec3 ter = toOsg(t);
unsigned int numDrawables = geode->getNumDrawables(); unsigned int numDrawables = geode->getNumDrawables();
Geometry* geom Geometry* geom
= static_cast<Geometry*>(geode->getDrawable(numDrawables - 1)); = static_cast<Geometry*>(geode->getDrawable(numDrawables - 1));
Vec3Array* posArray = static_cast<Vec3Array*>(geom->getColorArray()); Vec3Array* posArray = static_cast<Vec3Array*>(geom->getColorArray());
Vec3Array* tnormalArray;
if (use_tree_shadows || use_tree_normals)
{tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());}
if (posArray->size() if (posArray->size()
>= static_cast<Vec3Array*>(geom->getVertexArray())->size()) { >= static_cast<Vec3Array*>(geom->getVertexArray())->size()) {
Vec3Array* paramsArray Vec3Array* paramsArray
@@ -215,17 +198,11 @@ void addTreeToLeafGeode(Geode* geode, const SGVec3f& p, const SGVec3f& t)
Vec3 params = (*paramsArray)[0]; Vec3 params = (*paramsArray)[0];
geom = createTreeGeometry(params.x(), params.y(), params.z()); geom = createTreeGeometry(params.x(), params.y(), params.z());
posArray = static_cast<Vec3Array*>(geom->getColorArray()); posArray = static_cast<Vec3Array*>(geom->getColorArray());
if (use_tree_shadows || use_tree_normals)
{tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());}
geode->addDrawable(geom); geode->addDrawable(geom);
} }
posArray->insert(posArray->end(), 4, pos); posArray->insert(posArray->end(), 4, pos);
if (use_tree_shadows || use_tree_normals)
{tnormalArray->insert(tnormalArray->end(),4,ter);}
size_t numVerts = posArray->size(); size_t numVerts = posArray->size();
int imax = 2; for (int i = 0; i < 2; ++i) {
if (use_tree_shadows) {imax = 3;}
for (int i = 0; i < imax; ++i) {
DrawArrays* primSet DrawArrays* primSet
= static_cast<DrawArrays*>(geom->getPrimitiveSet(i)); = static_cast<DrawArrays*>(geom->getPrimitiveSet(i));
primSet->setCount(numVerts); primSet->setCount(numVerts);
@@ -278,7 +255,7 @@ struct AddTreesLeafObject
void operator() (LOD* lod, const TreeBin::Tree& tree) const void operator() (LOD* lod, const TreeBin::Tree& tree) const
{ {
Geode* geode = static_cast<Geode*>(lod->getChild(int(tree.position.x() * 10.0f) % lod->getNumChildren())); Geode* geode = static_cast<Geode*>(lod->getChild(int(tree.position.x() * 10.0f) % lod->getNumChildren()));
addTreeToLeafGeode(geode, tree.position, tree.tnormal); addTreeToLeafGeode(geode, tree.position);
} }
}; };
@@ -300,8 +277,7 @@ struct TreeTransformer
TreeBin::Tree operator()(const TreeBin::Tree& tree) const TreeBin::Tree operator()(const TreeBin::Tree& tree) const
{ {
Vec3 pos = toOsg(tree.position); Vec3 pos = toOsg(tree.position);
Vec3 norm = toOsg(tree.tnormal); return TreeBin::Tree(toSG(pos * mat));
return TreeBin::Tree(toSG(pos * mat),toSG(norm * mat));
} }
Matrix mat; Matrix mat;
}; };
@@ -357,20 +333,6 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
SGTreeBinList::iterator i; SGTreeBinList::iterator i;
use_tree_shadows = false;
use_tree_normals = false;
if (options) {
SGPropertyNode* propertyNode = options->getPropertyNode().get();
if (propertyNode) {
use_tree_shadows
= propertyNode->getBoolValue("/sim/rendering/random-vegetation-shadows",
use_tree_shadows);
use_tree_normals
= propertyNode->getBoolValue("/sim/rendering/random-vegetation-normals",
use_tree_normals);
}
}
for (i = forestList.begin(); i != forestList.end(); ++i) { for (i = forestList.begin(); i != forestList.end(); ++i) {
TreeBin* forest = *i; TreeBin* forest = *i;
@@ -381,7 +343,7 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
(!iter->second.lock(effect))) (!iter->second.lock(effect)))
{ {
SGPropertyNode_ptr effectProp = new SGPropertyNode; SGPropertyNode_ptr effectProp = new SGPropertyNode;
makeChild(effectProp, "inherits-from")->setStringValue(forest->teffect); makeChild(effectProp, "inherits-from")->setStringValue("Effects/tree");
SGPropertyNode* params = makeChild(effectProp, "parameters"); SGPropertyNode* params = makeChild(effectProp, "parameters");
// emphasize n = 0 // emphasize n = 0
params->getChild("texture", 0, true)->getChild("image", 0, true) params->getChild("texture", 0, true)->getChild("image", 0, true)
+5 -7
View File
@@ -36,10 +36,10 @@ namespace simgear
class TreeBin { class TreeBin {
public: public:
struct Tree { struct Tree {
SGVec3f position; Tree(const SGVec3f& p) :
SGVec3f tnormal; position(p)
Tree(const SGVec3f& p, const SGVec3f& t) : position(p),tnormal(t)
{ } { }
SGVec3f position;
}; };
typedef std::vector<Tree> TreeList; typedef std::vector<Tree> TreeList;
@@ -49,13 +49,11 @@ public:
float height; float height;
float width; float width;
std::string texture; std::string texture;
std::string teffect;
void insert(const Tree& t) void insert(const Tree& t)
{ _trees.push_back(t); } { _trees.push_back(t); }
void insert(const SGVec3f& p, int t, float s)
void insert(const SGVec3f& p, const SGVec3f& tnorm) { insert(Tree(p)); }
{insert(Tree(p,tnorm));}
unsigned getNumTrees() const unsigned getNumTrees() const
{ return _trees.size(); } { return _trees.size(); }
+31 -90
View File
@@ -51,7 +51,6 @@
#include <map> #include <map>
#include <simgear/compiler.h> #include <simgear/compiler.h>
#include <simgear/version.h>
#include "terrasync.hxx" #include "terrasync.hxx"
@@ -200,43 +199,6 @@ static unsigned int syncSlotForType(SyncItem::Type ty)
} }
} }
///////////////////////////////////////////////////////////////////////////////
// Base server query
///////////////////////////////////////////////////////////////////////////////
class ServerSelectQuery : public HTTP::Request
{
public:
ServerSelectQuery() :
HTTP::Request("http://scenery.flightgear.org/svn-server", "GET")
{
}
std::string svnUrl() const
{
std::string s = simgear::strutils::strip(m_url);
if (s.at(s.length() - 1) == '/') {
s = s.substr(0, s.length() - 1);
}
return s;
}
protected:
virtual void gotBodyData(const char* s, int n)
{
m_url.append(std::string(s, n));
}
virtual void onFail()
{
SG_LOG(SG_TERRASYNC, SG_ALERT, "Failed to query TerraSync SVN server");
HTTP::Request::onFail();
}
private:
std::string m_url;
};
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// SGTerraSync::SvnThread ///////////////////////////////////////////////////// // SGTerraSync::SvnThread /////////////////////////////////////////////////////
@@ -344,7 +306,7 @@ SGTerraSync::SvnThread::SvnThread() :
_stop(false), _stop(false),
_use_svn(true) _use_svn(true)
{ {
_http.setUserAgent("terrascenery-" SG_STRINGIZE(SIMGEAR_VERSION)); _http.setUserAgent("terrascenery-" SG_STRINGIZE(SG_VERSION));
} }
void SGTerraSync::SvnThread::stop() void SGTerraSync::SvnThread::stop()
@@ -370,7 +332,7 @@ bool SGTerraSync::SvnThread::start()
if (_local_dir=="") if (_local_dir=="")
{ {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Local cache directory is undefined."); "Cannot start scenery download. Local cache directory is undefined.");
_fail_count++; _fail_count++;
_stalled = true; _stalled = true;
@@ -380,7 +342,7 @@ bool SGTerraSync::SvnThread::start()
SGPath path(_local_dir); SGPath path(_local_dir);
if (!path.exists()) if (!path.exists())
{ {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Directory '" << _local_dir << "Cannot start scenery download. Directory '" << _local_dir <<
"' does not exist. Set correct directory path or create directory folder."); "' does not exist. Set correct directory path or create directory folder.");
_fail_count++; _fail_count++;
@@ -391,7 +353,7 @@ bool SGTerraSync::SvnThread::start()
path.append("version"); path.append("version");
if (path.exists()) if (path.exists())
{ {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Directory '" << _local_dir << "Cannot start scenery download. Directory '" << _local_dir <<
"' contains the base package. Use a separate directory."); "' contains the base package. Use a separate directory.");
_fail_count++; _fail_count++;
@@ -401,10 +363,17 @@ bool SGTerraSync::SvnThread::start()
_use_svn |= _use_built_in; _use_svn |= _use_built_in;
if ((_use_svn)&&(_svn_server==""))
{
SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Subversion scenery server is undefined.");
_fail_count++;
_stalled = true;
return false;
}
if ((!_use_svn)&&(_rsync_server=="")) if ((!_use_svn)&&(_rsync_server==""))
{ {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Rsync scenery server is undefined."); "Cannot start scenery download. Rsync scenery server is undefined.");
_fail_count++; _fail_count++;
_stalled = true; _stalled = true;
@@ -436,7 +405,7 @@ bool SGTerraSync::SvnThread::start()
// not really an alert - but we want to (always) see this message, so user is // not really an alert - but we want to (always) see this message, so user is
// aware we're downloading scenery (and using bandwidth). // aware we're downloading scenery (and using bandwidth).
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Starting automatic scenery download/synchronization. " "Starting automatic scenery download/synchronization. "
<< status << status
<< "Directory: '" << _local_dir << "'."); << "Directory: '" << _local_dir << "'.");
@@ -476,7 +445,7 @@ bool SGTerraSync::SvnThread::runExternalSyncCommand(const char* dir)
#else #else
command = buf.str(); command = buf.str();
#endif #endif
SG_LOG(SG_TERRASYNC,SG_DEBUG, "sync command '" << command << "'"); SG_LOG(SG_TERRAIN,SG_DEBUG, "sync command '" << command << "'");
#ifdef SG_WINDOWS #ifdef SG_WINDOWS
// tbd: does Windows support "popen"? // tbd: does Windows support "popen"?
@@ -491,7 +460,7 @@ bool SGTerraSync::SvnThread::runExternalSyncCommand(const char* dir)
if (rc) if (rc)
{ {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Failed to synchronize directory '" << dir << "', " << "Failed to synchronize directory '" << dir << "', " <<
"error code= " << rc); "error code= " << rc);
return false; return false;
@@ -504,32 +473,6 @@ void SGTerraSync::SvnThread::run()
_active = true; _active = true;
initCompletedTilesPersistentCache(); initCompletedTilesPersistentCache();
{
if (_svn_server.empty()) {
SG_LOG(SG_TERRASYNC,SG_INFO, "Querying closest TerraSync server");
ServerSelectQuery* ssq = new ServerSelectQuery;
HTTP::Request_ptr req = ssq;
_http.makeRequest(req);
while (!req->isComplete()) {
_http.update(20);
}
if (req->readyState() == HTTP::Request::DONE) {
_svn_server = ssq->svnUrl();
SG_LOG(SG_TERRASYNC,SG_INFO, "Closest TerraSync server:" << _svn_server);
} else {
SG_LOG(SG_TERRASYNC,SG_WARN, "Failed to query closest TerraSync server");
}
} else {
SG_LOG(SG_TERRASYNC,SG_INFO, "Explicit: TerraSync server:" << _svn_server);
}
if (_svn_server.empty()) {
// default value
_svn_server = "http://foxtrot.mgras.net:8080/terrascenery/trunk/data/Scenery";
}
}
if (_use_built_in) { if (_use_built_in) {
runInternal(); runInternal();
} else { } else {
@@ -552,7 +495,7 @@ void SGTerraSync::SvnThread::runExternal()
SyncItem::Status cacheStatus = isPathCached(next); SyncItem::Status cacheStatus = isPathCached(next);
if (cacheStatus != SyncItem::Invalid) { if (cacheStatus != SyncItem::Invalid) {
_cache_hits++; _cache_hits++;
SG_LOG(SG_TERRASYNC, SG_DEBUG, SG_LOG(SG_TERRAIN, SG_DEBUG,
"Cache hit for: '" << next._dir << "'"); "Cache hit for: '" << next._dir << "'");
next._status = cacheStatus; next._status = cacheStatus;
_freshTiles.push_back(next); _freshTiles.push_back(next);
@@ -582,7 +525,7 @@ void SGTerraSync::SvnThread::syncPathExternal(const SyncItem& next)
if (isNewDirectory) { if (isNewDirectory) {
int rc = path.create_dir( 0755 ); int rc = path.create_dir( 0755 );
if (rc) { if (rc) {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot create directory '" << path << "', return code = " << rc ); "Cannot create directory '" << path << "', return code = " << rc );
throw sg_exception("Cannot create directory for terrasync", path.str()); throw sg_exception("Cannot create directory for terrasync", path.str());
} }
@@ -605,10 +548,10 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
{ {
if (slot.repository.get()) { if (slot.repository.get()) {
if (slot.repository->isDoingSync()) { if (slot.repository->isDoingSync()) {
#if 1 #if 0
if (slot.stamp.elapsedMSec() > (int)slot.nextWarnTimeout) { if (slot.stamp.elapsedMSec() > slot.nextWarnTimeout) {
SG_LOG(SG_TERRASYNC, SG_INFO, "sync taking a long time:" << slot.currentItem._dir << " taken " << slot.stamp.elapsedMSec()); SG_LOG(SG_TERRAIN, SG_INFO, "sync taking a long time:" << slot.currentItem._dir << " taken " << slot.stamp.elapsedMSec());
SG_LOG(SG_TERRASYNC, SG_INFO, "HTTP request count:" << _http.hasActiveRequests()); SG_LOG(SG_TERRAIN, SG_INFO, "HTTP status:" << _http.hasActiveRequests());
slot.nextWarnTimeout += 10000; slot.nextWarnTimeout += 10000;
} }
#endif #endif
@@ -623,7 +566,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
fail(slot.currentItem); fail(slot.currentItem);
} else { } else {
updated(slot.currentItem, slot.isNewDirectory); updated(slot.currentItem, slot.isNewDirectory);
SG_LOG(SG_TERRASYNC, SG_DEBUG, "sync of " << slot.repository->baseUrl() << " finished (" SG_LOG(SG_TERRAIN, SG_DEBUG, "sync of " << slot.repository->baseUrl() << " finished ("
<< slot.stamp.elapsedMSec() << " msec"); << slot.stamp.elapsedMSec() << " msec");
} }
@@ -643,7 +586,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
if (slot.isNewDirectory) { if (slot.isNewDirectory) {
int rc = path.create_dir( 0755 ); int rc = path.create_dir( 0755 );
if (rc) { if (rc) {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot create directory '" << path << "', return code = " << rc ); "Cannot create directory '" << path << "', return code = " << rc );
fail(slot.currentItem); fail(slot.currentItem);
return; return;
@@ -662,7 +605,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
slot.nextWarnTimeout = 20000; slot.nextWarnTimeout = 20000;
slot.stamp.stamp(); slot.stamp.stamp();
slot.busy = true; slot.busy = true;
SG_LOG(SG_TERRASYNC, SG_INFO, "sync of " << slot.repository->baseUrl() << " started, queue size is " << slot.queue.size()); SG_LOG(SG_TERRAIN, SG_DEBUG, "sync of " << slot.repository->baseUrl() << " started, queue size is " << slot.queue.size());
} }
} }
@@ -683,7 +626,7 @@ void SGTerraSync::SvnThread::runInternal()
SyncItem::Status cacheStatus = isPathCached(next); SyncItem::Status cacheStatus = isPathCached(next);
if (cacheStatus != SyncItem::Invalid) { if (cacheStatus != SyncItem::Invalid) {
_cache_hits++; _cache_hits++;
SG_LOG(SG_TERRASYNC, SG_DEBUG, "\nTerraSync Cache hit for: '" << next._dir << "'"); SG_LOG(SG_TERRAIN, SG_DEBUG, "\nTerraSync Cache hit for: '" << next._dir << "'");
next._status = cacheStatus; next._status = cacheStatus;
_freshTiles.push_back(next); _freshTiles.push_back(next);
_is_dirty = true; _is_dirty = true;
@@ -740,8 +683,6 @@ void SGTerraSync::SvnThread::fail(SyncItem failedItem)
_fail_count++; _fail_count++;
failedItem._status = SyncItem::Failed; failedItem._status = SyncItem::Failed;
_freshTiles.push_back(failedItem); _freshTiles.push_back(failedItem);
SG_LOG(SG_TERRASYNC,SG_INFO,
"Failed to sync'" << failedItem._dir << "'");
_completedTiles[ failedItem._dir ] = now + UpdateInterval::FailedAttempt; _completedTiles[ failedItem._dir ] = now + UpdateInterval::FailedAttempt;
_is_dirty = true; _is_dirty = true;
} }
@@ -766,7 +707,7 @@ void SGTerraSync::SvnThread::updated(SyncItem item, bool isNewDirectory)
time_t now = time(0); time_t now = time(0);
_consecutive_errors = 0; _consecutive_errors = 0;
_success_count++; _success_count++;
SG_LOG(SG_TERRASYNC,SG_INFO, SG_LOG(SG_TERRAIN,SG_INFO,
"Successfully synchronized directory '" << item._dir << "'"); "Successfully synchronized directory '" << item._dir << "'");
item._status = SyncItem::Updated; item._status = SyncItem::Updated;
@@ -792,7 +733,7 @@ void SGTerraSync::SvnThread::initCompletedTilesPersistentCache()
try { try {
readProperties(_persistentCachePath.str(), cacheRoot); readProperties(_persistentCachePath.str(), cacheRoot);
} catch (sg_exception& e) { } catch (sg_exception& e) {
SG_LOG(SG_TERRASYNC, SG_INFO, "corrupted persistent cache, discarding"); SG_LOG(SG_TERRAIN, SG_INFO, "corrupted persistent cache, discarding");
return; return;
} }
@@ -853,7 +794,7 @@ SGTerraSync::SGTerraSync() :
_inited(false) _inited(false)
{ {
_svnThread = new SvnThread(); _svnThread = new SvnThread();
_log = new BufferedLogCallback(SG_TERRASYNC, SG_INFO); _log = new BufferedLogCallback(SG_TERRAIN, SG_INFO);
_log->truncateAt(255); _log->truncateAt(255);
sglog().addCallback(_log); sglog().addCallback(_log);
@@ -978,13 +919,13 @@ void SGTerraSync::update(double)
{ {
if (_svnThread->_stalled) if (_svnThread->_stalled)
{ {
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Automatic scenery download/synchronization stalled. Too many errors."); "Automatic scenery download/synchronization stalled. Too many errors.");
} }
else else
{ {
// not really an alert - just always show this message // not really an alert - just always show this message
SG_LOG(SG_TERRASYNC,SG_ALERT, SG_LOG(SG_TERRAIN,SG_ALERT,
"Automatic scenery download/synchronization has stopped."); "Automatic scenery download/synchronization has stopped.");
} }
_stalledNode->setBoolValue(_svnThread->_stalled); _stalledNode->setBoolValue(_svnThread->_stalled);
-22
View File
@@ -25,13 +25,11 @@
#include "SGSceneFeatures.hxx" #include "SGSceneFeatures.hxx"
#include <osg/Version>
#include <osg/FragmentProgram> #include <osg/FragmentProgram>
#include <osg/VertexProgram> #include <osg/VertexProgram>
#include <osg/Point> #include <osg/Point>
#include <osg/PointSprite> #include <osg/PointSprite>
#include <osg/Texture> #include <osg/Texture>
#include <osg/GLExtensions>
#include <OpenThreads/Mutex> #include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock> #include <OpenThreads/ScopedLock>
@@ -86,18 +84,12 @@ SGSceneFeatures::setTextureCompression(osg::Texture* texture) const
bool bool
SGSceneFeatures::getHavePointSprites(unsigned contextId) const SGSceneFeatures::getHavePointSprites(unsigned contextId) const
{ {
#if OSG_VERSION_LESS_THAN(3,3,4)
return osg::PointSprite::isPointSpriteSupported(contextId); return osg::PointSprite::isPointSpriteSupported(contextId);
#else
const osg::GLExtensions* ex = osg::GLExtensions::Get(contextId, true);
return ex && ex->isPointSpriteSupported;
#endif
} }
bool bool
SGSceneFeatures::getHaveFragmentPrograms(unsigned contextId) const SGSceneFeatures::getHaveFragmentPrograms(unsigned contextId) const
{ {
#if OSG_VERSION_LESS_THAN(3,3,4)
const osg::FragmentProgram::Extensions* fpe; const osg::FragmentProgram::Extensions* fpe;
fpe = osg::FragmentProgram::getExtensions(contextId, true); fpe = osg::FragmentProgram::getExtensions(contextId, true);
if (!fpe) if (!fpe)
@@ -106,16 +98,11 @@ SGSceneFeatures::getHaveFragmentPrograms(unsigned contextId) const
return false; return false;
return true; return true;
#else
const osg::GLExtensions* ex = osg::GLExtensions::Get(contextId, true);
return ex && ex->isFragmentProgramSupported;
#endif
} }
bool bool
SGSceneFeatures::getHaveVertexPrograms(unsigned contextId) const SGSceneFeatures::getHaveVertexPrograms(unsigned contextId) const
{ {
#if OSG_VERSION_LESS_THAN(3,3,4)
const osg::VertexProgram::Extensions* vpe; const osg::VertexProgram::Extensions* vpe;
vpe = osg::VertexProgram::getExtensions(contextId, true); vpe = osg::VertexProgram::getExtensions(contextId, true);
if (!vpe) if (!vpe)
@@ -124,10 +111,6 @@ SGSceneFeatures::getHaveVertexPrograms(unsigned contextId) const
return false; return false;
return true; return true;
#else
const osg::GLExtensions* ex = osg::GLExtensions::Get(contextId, true);
return ex && ex->isVertexProgramSupported;
#endif
} }
bool bool
@@ -141,7 +124,6 @@ SGSceneFeatures::getHaveShaderPrograms(unsigned contextId) const
bool bool
SGSceneFeatures::getHavePointParameters(unsigned contextId) const SGSceneFeatures::getHavePointParameters(unsigned contextId) const
{ {
#if OSG_VERSION_LESS_THAN(3,3,4)
const osg::Point::Extensions* pe; const osg::Point::Extensions* pe;
pe = osg::Point::getExtensions(contextId, true); pe = osg::Point::getExtensions(contextId, true);
if (!pe) if (!pe)
@@ -149,9 +131,5 @@ SGSceneFeatures::getHavePointParameters(unsigned contextId) const
if (!pe->isPointParametersSupported()) if (!pe->isPointParametersSupported())
return false; return false;
return true; return true;
#else
const osg::GLExtensions* ex = osg::GLExtensions::Get(contextId, true);
return ex && ex->isPointParametersSupported;
#endif
} }
-1
View File
@@ -18,4 +18,3 @@
#cmakedefine SYSTEM_EXPAT #cmakedefine SYSTEM_EXPAT
#cmakedefine ENABLE_SOUND #cmakedefine ENABLE_SOUND
#cmakedefine ENABLE_CURL
+3 -6
View File
@@ -402,8 +402,7 @@ void SGSampleGroup::set_volume( float vol )
// set the source position and orientation of all managed sounds // set the source position and orientation of all managed sounds
void SGSampleGroup::update_pos_and_orientation() { void SGSampleGroup::update_pos_and_orientation() {
SGVec3d base_position = SGVec3d::fromGeod(_base_pos); SGVec3d position = SGVec3d::fromGeod(_base_pos) - _smgr->get_position();
SGVec3d smgr_position = _smgr->get_position();
SGQuatd hlOr = SGQuatd::fromLonLat(_base_pos); SGQuatd hlOr = SGQuatd::fromLonLat(_base_pos);
SGQuatd ec2body = hlOr*_orientation; SGQuatd ec2body = hlOr*_orientation;
@@ -419,14 +418,12 @@ void SGSampleGroup::update_pos_and_orientation() {
sample->set_master_volume( _volume ); sample->set_master_volume( _volume );
sample->set_orientation( _orientation ); sample->set_orientation( _orientation );
sample->set_rotation( ec2body ); sample->set_rotation( ec2body );
sample->set_position(base_position); sample->set_position( position );
sample->set_velocity( velocity ); sample->set_velocity( velocity );
// Test if a sample is farther away than max distance, if so // Test if a sample is farther away than max distance, if so
// stop the sound playback and free it's source. // stop the sound playback and free it's source.
if (!_tied_to_listener) { if (!_tied_to_listener) {
sample->update_pos_and_orientation();
SGVec3d position = sample->get_position() - smgr_position;
float max2 = sample->get_max_dist() * sample->get_max_dist(); float max2 = sample->get_max_dist() * sample->get_max_dist();
float dist2 = position[0]*position[0] float dist2 = position[0]*position[0]
+ position[1]*position[1] + position[2]*position[2]; + position[1]*position[1] + position[2]*position[2];
@@ -452,7 +449,7 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample )
} else { } else {
sample->update_pos_and_orientation(); sample->update_pos_and_orientation();
orientation = sample->get_orientation(); orientation = sample->get_orientation();
position = sample->get_position() - _smgr->get_position(); position = sample->get_position();
velocity = sample->get_velocity(); velocity = sample->get_velocity();
} }
+4 -28
View File
@@ -28,7 +28,6 @@
#include <stdlib.h> // rand(), free() #include <stdlib.h> // rand(), free()
#include <cstring> #include <cstring>
#include <stdio.h>
#include <simgear/debug/logstream.hxx> #include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx> #include <simgear/structure/exception.hxx>
@@ -79,12 +78,8 @@ SGSoundSample::SGSoundSample() :
_playing(false), _playing(false),
_static_changed(true), _static_changed(true),
_out_of_range(false), _out_of_range(false),
_is_file(false), _is_file(false)
_use_pos_props(false)
{ {
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
} }
// constructor // constructor
@@ -119,14 +114,10 @@ SGSoundSample::SGSoundSample(const char *file, const SGPath& currentDir) :
_playing(false), _playing(false),
_static_changed(true), _static_changed(true),
_out_of_range(false), _out_of_range(false),
_is_file(true), _is_file(true)
_use_pos_props(false)
{ {
SGPath p = simgear::ResourceManager::instance()->findPath(file, currentDir); SGPath p = simgear::ResourceManager::instance()->findPath(file, currentDir);
_refname = p.str(); _refname = p.str();
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
} }
// constructor // constructor
@@ -161,14 +152,10 @@ SGSoundSample::SGSoundSample( const unsigned char** data,
_playing(false), _playing(false),
_static_changed(true), _static_changed(true),
_out_of_range(false), _out_of_range(false),
_is_file(false), _is_file(false)
_use_pos_props(false)
{ {
SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" );
_data = (unsigned char*)*data; *data = NULL; _data = (unsigned char*)*data; *data = NULL;
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
} }
// constructor // constructor
@@ -202,14 +189,10 @@ SGSoundSample::SGSoundSample( void** data, int len, int freq, int format ) :
_playing(false), _playing(false),
_static_changed(true), _static_changed(true),
_out_of_range(false), _out_of_range(false),
_is_file(false), _is_file(false)
_use_pos_props(false)
{ {
SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" ); SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" );
_data = (unsigned char*)*data; *data = NULL; _data = (unsigned char*)*data; *data = NULL;
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
} }
@@ -220,17 +203,10 @@ SGSoundSample::~SGSoundSample() {
void SGSoundSample::update_pos_and_orientation() { void SGSoundSample::update_pos_and_orientation() {
if (_use_pos_props) {
if (_pos_prop[0]) _absolute_pos[0] = _pos_prop[0]->getDoubleValue();
if (_pos_prop[1]) _absolute_pos[1] = _pos_prop[1]->getDoubleValue();
if (_pos_prop[2]) _absolute_pos[2] = _pos_prop[2]->getDoubleValue();
}
else {
_absolute_pos = _base_pos; _absolute_pos = _base_pos;
if (_relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) { if (_relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) {
_absolute_pos += _rotation.rotate( _relative_pos ); _absolute_pos += _rotation.rotate( _relative_pos );
} }
}
_orivec = SGVec3f::zeros(); _orivec = SGVec3f::zeros();
if ( _direction[0] || _direction[1] || _direction[2] ) { if ( _direction[0] || _direction[1] || _direction[2] ) {

Some files were not shown because too many files have changed in this diff Show More