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 1438 additions and 3475 deletions
+19 -79
View File
@@ -1,29 +1,14 @@
cmake_minimum_required (VERSION 2.8.11)
if(COMMAND cmake_policy)
if(POLICY CMP0054)
cmake_policy(SET CMP0054 NEW)
endif()
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW)
endif()
endif()
cmake_minimum_required (VERSION 2.6.4)
include (CheckFunctionExists)
include (CheckIncludeFile)
include (CheckLibraryExists)
include (CheckCXXSourceCompiles)
include (CheckCXXCompilerFlag)
include (GenerateExportHeader)
project(SimGear)
# using 10.7 because boost requires libc++ and 10.6 doesn't include it
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)
file(READ version versionFile)
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
# 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
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}")
#####################################################################################
@@ -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_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_CURL "Set to ON to use libCurl as the HTTP client backend" OFF)
if (MSVC)
GET_FILENAME_COMPONENT(PARENT_DIR ${PROJECT_BINARY_DIR} PATH)
@@ -175,23 +164,13 @@ endif (MSVC AND MSVC_3RDPARTY_ROOT)
if(APPLE)
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()
# Somehow this only works if included before searching for Boost...
include(BoostTestTargets)
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)
message(STATUS "SimGear mode: HEADLESS")
@@ -209,11 +188,7 @@ else()
endif(SIMGEAR_HEADLESS)
find_package(ZLIB REQUIRED)
if (ENABLE_CURL)
find_package(CURL REQUIRED)
message(STATUS "Curl HTTP client: ENABLED")
endif()
find_package(Threads REQUIRED)
if (SYSTEM_EXPAT)
message(STATUS "Requested to use system Expat library, forcing SIMGEAR_SHARED to true")
@@ -325,12 +300,11 @@ if(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# Boost redeclares class members
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual -Wno-redeclared-class-member")
set(WARNING_FLAGS_C "-Wall")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
set(WARNING_FLAGS_CXX "-Wall -Wno-overloaded-virtual")
set(WARNING_FLAGS_C "-Wall")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
endif()
if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
@@ -380,7 +354,6 @@ include_directories(${OPENSCENEGRAPH_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
${ZLIB_INCLUDE_DIR}
${OPENAL_INCLUDE_DIR}
${CURL_INCLUDE_DIRS}
)
add_definitions(-DHAVE_CONFIG_H)
@@ -409,8 +382,7 @@ set(TEST_LIBS_INTERNAL_CORE
${WINSOCK_LIBRARY}
${RT_LIBRARY}
${DL_LIBRARY}
${COCOA_LIBRARY}
${CURL_LIBRARIES})
${COCOA_LIBRARY})
set(TEST_LIBS SimGearCore ${TEST_LIBS_INTERNAL_CORE})
if(NOT SIMGEAR_HEADLESS)
@@ -424,40 +396,6 @@ include_directories(3rdparty/utf8/source)
add_subdirectory(3rdparty)
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
#-----------------------------------------------------------------------------
@@ -467,3 +405,5 @@ CONFIGURE_FILE(
IMMEDIATE @ONLY)
ADD_CUSTOM_TARGET(uninstall
"${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 VERSION ${SIMGEAR_VERSION})
set_property(TARGET SimGearCore PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
install(TARGETS SimGearCore
EXPORT SimGearTargets
LIBRARY DESTINATION
${CMAKE_INSTALL_LIBDIR})
install(TARGETS SimGearCore EXPORT SimGearCoreConfig LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT SimGearCoreConfig DESTINATION share/SimGearCore)
if(NOT SIMGEAR_HEADLESS)
add_library(SimGearScene SHARED ${sceneSources})
@@ -66,10 +64,8 @@ if(SIMGEAR_SHARED)
set_property(TARGET SimGearScene PROPERTY SOVERSION ${SIMGEAR_SOVERSION})
# EXPORT SimGearSceneConfig
install(TARGETS SimGearScene
EXPORT SimGearTargets
LIBRARY
DESTINATION ${CMAKE_INSTALL_LIBDIR} )
install(TARGETS SimGearScene LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} )
# install(EXPORT SimGearSceneConfig DESTINATION share/SimGearScene)
endif()
else()
@@ -94,9 +90,7 @@ else()
endforeach()
add_library(SimGearCore STATIC ${coreSources} ${localExpatSources})
install(TARGETS SimGearCore
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS SimGearCore ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
if(NOT SIMGEAR_HEADLESS)
get_property(FG_GROUPS_SCENE_SOURCES_C GLOBAL PROPERTY FG_GROUPS_SCENE_SOURCES_C)
@@ -118,9 +112,7 @@ else()
endforeach()
add_library(SimGearScene STATIC ${sceneSources})
install(TARGETS SimGearScene
EXPORT SimGearTargets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(TARGETS SimGearScene ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif(NOT SIMGEAR_HEADLESS)
endif(SIMGEAR_SHARED)
@@ -130,8 +122,7 @@ target_link_libraries(SimGearCore
${DL_LIBRARY}
${EXPAT_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
${COCOA_LIBRARY}
${CURL_LIBRARIES})
${COCOA_LIBRARY})
if(NOT SIMGEAR_HEADLESS)
target_link_libraries(SimGearScene
+1 -1
View File
@@ -43,7 +43,7 @@ public:
void removeChild(BVHNode* child);
unsigned getNumChildren() const
{ return static_cast<unsigned>(_children.size()); }
{ return _children.size(); }
const BVHNode* getChild(unsigned i) const
{ if (_children.size() <= i) return 0; return _children[i]; }
BVHNode* getChild(unsigned i)
+2 -2
View File
@@ -31,13 +31,13 @@ public:
virtual ~BVHStaticData() {}
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
{ return _vertices[i]; }
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
{ if (_materials.size() <= i) return 0; return _materials[i]; }
+23 -12
View File
@@ -207,6 +207,19 @@ namespace canvas
//----------------------------------------------------------------------------
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
{
return _parent.lock();
return _parent;
}
//----------------------------------------------------------------------------
@@ -311,9 +324,8 @@ namespace canvas
//----------------------------------------------------------------------------
bool Element::ascend(EventVisitor& visitor)
{
ElementPtr parent = getParent();
if( parent )
return parent->accept(visitor);
if( _parent )
return _parent->accept(visitor);
return true;
}
@@ -362,9 +374,9 @@ namespace canvas
EventPropagationPath path;
path.push_back( EventTarget(this) );
for( ElementPtr parent = getParent();
parent.valid();
parent = parent->getParent() )
for( Element* parent = _parent;
parent != NULL;
parent = parent->_parent )
path.push_front( EventTarget(parent) );
CanvasPtr canvas = _canvas.lock();
@@ -760,7 +772,7 @@ namespace canvas
Element::Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent ):
Element* parent ):
PropertyBasedElement(node),
_canvas( canvas ),
_parent( parent ),
@@ -859,12 +871,11 @@ namespace canvas
Element::getParentStyle(const SGPropertyNode* child) const
{
// Try to get value from parent...
ElementPtr parent = getParent();
if( parent )
if( _parent )
{
Style::const_iterator style =
parent->_style.find(child->getNameString());
if( style != parent->_style.end() )
_parent->_style.find(child->getNameString());
if( style != _parent->_style.end() )
return style->second;
}
+3 -3
View File
@@ -232,8 +232,8 @@ namespace canvas
class RelativeScissor;
CanvasWeakPtr _canvas;
ElementWeakPtr _parent;
CanvasWeakPtr _canvas;
Element *_parent;
mutable uint32_t _attributes_dirty;
@@ -256,7 +256,7 @@ namespace canvas
Element( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent );
Element* parent );
/**
* 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,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent ):
Element* parent ):
Element(canvas, node, parent_style, parent)
{
staticInit();
+1 -1
View File
@@ -45,7 +45,7 @@ namespace canvas
Group( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style = Style(),
ElementWeakPtr parent = 0 );
Element* parent = 0 );
virtual ~Group();
ElementPtr createChild( const std::string& type,
+1 -1
View File
@@ -112,7 +112,7 @@ namespace canvas
Image::Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent ):
Element* parent ):
Element(canvas, node, parent_style, parent),
_texture(new osg::Texture2D),
_node_src_rect( node->getNode("source", 0, true) ),
+1 -1
View File
@@ -50,7 +50,7 @@ namespace canvas
Image( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style = Style(),
ElementWeakPtr parent = 0 );
Element* parent = 0 );
virtual ~Image();
virtual void update(double dt);
+66 -104
View File
@@ -44,7 +44,6 @@ namespace canvas
//----------------------------------------------------------------------------
const std::string GEO = "-geo";
const std::string HDG = "hdg";
const std::string Map::TYPE_NAME = "map";
//----------------------------------------------------------------------------
@@ -62,7 +61,7 @@ namespace canvas
Map::Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent ):
Element* parent ):
Group(canvas, node, parent_style, parent),
// TODO make projection configurable
_projection(new SansonFlamsteedProjection),
@@ -113,50 +112,87 @@ namespace canvas
//----------------------------------------------------------------------------
void Map::childAdded(SGPropertyNode* parent, SGPropertyNode* child)
{
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
if( !boost::ends_with(child->getNameString(), GEO) )
return Element::childAdded(parent, child);
_geo_nodes[child].reset(new GeoNodePair());
}
//----------------------------------------------------------------------------
void Map::childRemoved(SGPropertyNode* parent, SGPropertyNode* child)
{
if( boost::ends_with(child->getNameString(), GEO) )
// TODO remove from other node
_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
if( !boost::ends_with(child->getNameString(), GEO) )
return Element::childRemoved(parent, child);
// TODO remove from other node
_geo_nodes.erase(child);
}
//----------------------------------------------------------------------------
void Map::valueChanged(SGPropertyNode* child)
void Map::valueChanged(SGPropertyNode * child)
{
if( child->getParent() != _node )
const std::string& name = child->getNameString();
if( !boost::ends_with(name, GEO) )
return Group::valueChanged(child);
GeoNodes::iterator it_geo_node = _geo_nodes.find(child);
if( it_geo_node == _geo_nodes.end() )
LOG_GEO_RET("geo node not found!")
GeoNodePair* geo_node = it_geo_node->second.get();
geo_node->setDirty();
if( geo_node->getStatus() & GeoNodePair::INCOMPLETE )
{
const std::string& name = child->getNameString();
// Detect lat, lon tuples...
GeoCoord coord = parseGeoCoord(child->getStringValue());
int index_other = -1;
if( boost::ends_with(name, GEO) )
return geoNodeChanged(child);
else if( name == HDG )
return hdgNodeChanged(child);
switch( coord.type )
{
case GeoCoord::LATITUDE:
index_other = child->getIndex() + 1;
geo_node->setNodeLat(child);
break;
case GeoCoord::LONGITUDE:
index_other = child->getIndex() - 1;
geo_node->setNodeLon(child);
break;
default:
LOG_GEO_RET("Invalid geo coord")
}
SGPropertyNode *other = child->getParent()->getChild(name, index_other);
if( !other )
return;
GeoCoord coord_other = parseGeoCoord(other->getStringValue());
if( coord_other.type == GeoCoord::INVALID
|| coord_other.type == coord.type )
return;
GeoNodes::iterator it_geo_node_other = _geo_nodes.find(other);
if( it_geo_node_other == _geo_nodes.end() )
LOG_GEO_RET("other geo node not found!")
GeoNodePair* geo_node_other = it_geo_node_other->second.get();
// Let use both nodes use the same GeoNodePair instance
if( geo_node_other != geo_node )
it_geo_node_other->second = it_geo_node->second;
if( coord_other.type == GeoCoord::LATITUDE )
geo_node->setNodeLat(other);
else
geo_node->setNodeLon(other);
// Set name for resulting screen coordinate nodes
geo_node->setTargetName( name.substr(0, name.length() - GEO.length()) );
}
return Group::valueChanged(child);
}
//----------------------------------------------------------------------------
void Map::childChanged(SGPropertyNode* child)
void Map::childChanged(SGPropertyNode * child)
{
if( child->getParent() != _node )
return Group::childChanged(child);
@@ -165,14 +201,8 @@ namespace canvas
|| child->getNameString() == "ref-lon" )
_projection->setWorldPosition( _node->getDoubleValue("ref-lat"),
_node->getDoubleValue("ref-lon") );
else if( child->getNameString() == HDG )
{
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" )
@@ -183,74 +213,6 @@ namespace canvas
_projection_dirty = true;
}
//----------------------------------------------------------------------------
void Map::geoNodeChanged(SGPropertyNode* child)
{
GeoNodes::iterator it_geo_node = _geo_nodes.find(child);
if( it_geo_node == _geo_nodes.end() )
LOG_GEO_RET("GeoNode not found!")
GeoNodePair* geo_node = it_geo_node->second.get();
geo_node->setDirty();
if( !(geo_node->getStatus() & GeoNodePair::INCOMPLETE) )
return;
// Detect lat, lon tuples...
GeoCoord coord = parseGeoCoord(child->getStringValue());
int index_other = -1;
switch( coord.type )
{
case GeoCoord::LATITUDE:
index_other = child->getIndex() + 1;
geo_node->setNodeLat(child);
break;
case GeoCoord::LONGITUDE:
index_other = child->getIndex() - 1;
geo_node->setNodeLon(child);
break;
default:
LOG_GEO_RET("Invalid geo coord")
}
const std::string& name = child->getNameString();
SGPropertyNode *other = child->getParent()->getChild(name, index_other);
if( !other )
return;
GeoCoord coord_other = parseGeoCoord(other->getStringValue());
if( coord_other.type == GeoCoord::INVALID
|| coord_other.type == coord.type )
return;
GeoNodes::iterator it_geo_node_other = _geo_nodes.find(other);
if( it_geo_node_other == _geo_nodes.end() )
LOG_GEO_RET("other geo node not found!")
GeoNodePair* geo_node_other = it_geo_node_other->second.get();
// Let use both nodes use the same GeoNodePair instance
if( geo_node_other != geo_node )
it_geo_node_other->second = it_geo_node->second;
if( coord_other.type == GeoCoord::LATITUDE )
geo_node->setNodeLat(other);
else
geo_node->setNodeLon(other);
// Set name for resulting screen coordinate nodes
geo_node->setTargetName( name.substr(0, name.length() - GEO.length()) );
}
//----------------------------------------------------------------------------
void Map::hdgNodeChanged(SGPropertyNode* child)
{
child->getParent()->setFloatValue(
"tf[0]/rot",
SGMiscf::deg2rad(child->getFloatValue() - _projection->orientation())
);
}
//----------------------------------------------------------------------------
Map::GeoCoord Map::parseGeoCoord(const std::string& val) const
{
+2 -10
View File
@@ -24,7 +24,6 @@
#include <boost/shared_ptr.hpp>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
namespace simgear
{
@@ -42,7 +41,7 @@ namespace canvas
Map( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent = 0 );
Element* parent = 0 );
virtual ~Map();
virtual void update(double dt);
@@ -60,18 +59,14 @@ namespace canvas
typedef boost::unordered_map< SGPropertyNode*,
boost::shared_ptr<GeoNodePair>
> GeoNodes;
typedef boost::unordered_set<SGPropertyNode*> NodeSet;
GeoNodes _geo_nodes;
NodeSet _hdg_nodes;
boost::shared_ptr<HorizontalProjection> _projection;
bool _projection_dirty;
struct GeoCoord
{
GeoCoord():
type(INVALID),
value(0)
type(INVALID)
{}
enum
{
@@ -82,9 +77,6 @@ namespace canvas
double value;
};
void geoNodeChanged(SGPropertyNode * child);
void hdgNodeChanged(SGPropertyNode * child);
GeoCoord parseGeoCoord(const std::string& val) const;
};
+1 -1
View File
@@ -531,7 +531,7 @@ namespace canvas
Path::Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent ):
Element* parent ):
Element(canvas, node, parent_style, parent),
_path( new PathDrawable(this) )
{
+1 -1
View File
@@ -36,7 +36,7 @@ namespace canvas
Path( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent = 0 );
Element* parent = 0 );
virtual ~Path();
virtual void update(double dt);
+3 -18
View File
@@ -159,12 +159,8 @@ namespace canvas
if( empty() )
return pos;
#if OSG_VERSION_LESS_THAN(3,3,5)
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;
if( global_i == _begin )
@@ -198,12 +194,7 @@ namespace canvas
return cursorPos(0);
GlyphQuads::Glyphs const& glyphs = _quads->_glyphs;
#if OSG_VERSION_LESS_THAN(3,3,5)
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 character_width = _text->getCharacterHeight()
@@ -636,13 +627,7 @@ namespace canvas
const GlyphQuads& quads = _textureGlyphQuadMap.begin()->second;
const GlyphQuads::Glyphs& glyphs = quads._glyphs;
#if OSG_VERSION_LESS_THAN(3,3,5)
GlyphQuads::Coords2 const& coords = quads._coords;
#else
GlyphQuads::Coords2 refCoords = quads._coords;
GlyphQuads::Coords2::element_type &coords = *refCoords.get();
#endif
const GlyphQuads::Coords2& coords = quads._coords;
const GlyphQuads::LineNumbers& line_numbers = quads._lineNumbers;
float wr = _characterHeight / getCharacterAspectRatio();
@@ -740,7 +725,7 @@ namespace canvas
Text::Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent ):
Element* parent ):
Element(canvas, node, parent_style, parent),
_text( new Text::TextOSG(this) )
{
+1 -1
View File
@@ -40,7 +40,7 @@ namespace canvas
Text( const CanvasWeakPtr& canvas,
const SGPropertyNode_ptr& node,
const Style& parent_style,
ElementWeakPtr parent = 0 );
Element* parent = 0 );
~Text();
void setText(const char* text);
+11 -28
View File
@@ -34,10 +34,7 @@ namespace canvas
public:
struct ScreenPosition
{
ScreenPosition():
x(0),
y(0)
{}
ScreenPosition() {}
ScreenPosition(double x, double y):
x(x),
@@ -70,11 +67,8 @@ namespace canvas
public:
HorizontalProjection():
_ref_lat(0),
_ref_lon(0),
_angle(0),
_cos_angle(1),
_sin_angle(0),
_cos_rot(1),
_sin_rot(0),
_range(5)
{
setScreenRange(200);
@@ -94,19 +88,9 @@ namespace canvas
*/
void setOrientation(float hdg)
{
_angle = hdg;
hdg = SGMiscf::deg2rad(hdg);
_sin_angle = sin(hdg);
_cos_angle = cos(hdg);
}
/**
* Get orientation/heading of the projection (in degree)
*/
float orientation() const
{
return _angle;
_sin_rot = sin(hdg);
_cos_rot = cos(hdg);
}
void setRange(double range)
@@ -130,8 +114,8 @@ namespace canvas
pos.y *= scale;
return ScreenPosition
(
_cos_angle * pos.x - _sin_angle * pos.y,
-_sin_angle * pos.x - _cos_angle * pos.y
_cos_rot * pos.x - _sin_rot * 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;
double _ref_lat, ///<! Reference latitude (radian)
_ref_lon, ///<! Reference latitude (radian)
_angle, ///<! Map rotation angle (degree)
_cos_angle,
_sin_angle,
double _ref_lat,
_ref_lon,
_cos_rot,
_sin_rot,
_range;
};
-6
View File
@@ -190,12 +190,6 @@ inline int (isnan)(double r) { return !(r <= 0 || r >= 0); }
# define DEPRECATED
#endif
#if defined(__clang__)
# define SG_NO_RETURN [[noreturn]]
#else
# define SG_NO_RETURN
#endif
//
// No user modifiable definitions beyond here.
//
+1 -2
View File
@@ -32,8 +32,7 @@ typedef enum {
SG_SOUND = 0x00200000,
SG_NAVAID = 0x00400000,
SG_GUI = 0x00800000,
SG_TERRASYNC = 0x01000000,
SG_UNDEFD = 0x02000000, // For range checking
SG_UNDEFD = 0x01000000, // For range checking
SG_ALL = 0xFFFFFFFF
} sgDebugClass;
-1
View File
@@ -71,7 +71,6 @@ const char* debugClassToString(sgDebugClass c)
case SG_SOUND: return "sound";
case SG_NAVAID: return "navaid";
case SG_GUI: return "gui";
case SG_TERRASYNC: return "terrasync";
default: return "unknown";
}
}
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$
**************************************************************************/
#include <cmath>
#include <math.h>
#include "jupiter.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$
**************************************************************************/
#include <cmath>
#include <math.h>
#include "mars.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$
**************************************************************************/
#include <cmath>
#include <math.h>
#include "mercury.hxx"
+1 -1
View File
@@ -25,7 +25,7 @@
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <cmath>
#include <math.h>
#include "neptune.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$
**************************************************************************/
#include <cmath>
#include <math.h>
#include "saturn.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$
**************************************************************************/
#include <cmath>
#include <math.h>
#include <simgear/debug/logstream.hxx>
+1 -1
View File
@@ -41,7 +41,7 @@ public:
bool load( const SGPath& path );
// stars
inline int getNumStars() const { return static_cast<int>(_stars.size()); }
inline int getNumStars() const { return _stars.size(); }
inline SGVec3d *getStars() { return &(_stars[0]); }
private:
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$
**************************************************************************/
#include <cmath>
#include <math.h>
#include "uranus.hxx"
+1 -1
View File
@@ -22,7 +22,7 @@
* $Id$
**************************************************************************/
#include <cmath>
#include <math.h>
#include "venus.hxx"
+2 -5
View File
@@ -18,6 +18,7 @@ set(HEADERS
HTTPFileRequest.hxx
HTTPMemoryRequest.hxx
HTTPRequest.hxx
HTTPContentDecode.hxx
DAVMultiStatus.hxx
SVNRepository.hxx
SVNDirectory.hxx
@@ -40,17 +41,13 @@ set(SOURCES
HTTPFileRequest.cxx
HTTPMemoryRequest.cxx
HTTPRequest.cxx
HTTPContentDecode.cxx
DAVMultiStatus.cxx
SVNRepository.cxx
SVNDirectory.cxx
SVNReportParser.cxx
)
if (NOT ENABLE_CURL)
list(APPEND SOURCES HTTPContentDecode.cxx)
list(APPEND HEADERS HTTPContentDecode.hxx)
endif()
simgear_component(io io "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS)
+4 -4
View File
@@ -193,7 +193,7 @@ public:
{
if (tagStack.empty()) {
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);
} else {
@@ -202,7 +202,7 @@ public:
// not at the root element
if (tagStack.back() == DAV_MULTISTATUS_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);
}
}
@@ -362,7 +362,7 @@ void DAVMultiStatus::parseXML(const char* data, int size)
}
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)
<< " column " << XML_GetCurrentColumnNumber(_d->xmlParser));
@@ -376,7 +376,7 @@ void DAVMultiStatus::finishParse()
{
if (_d->parserInited) {
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)
<< " column " << XML_GetCurrentColumnNumber(_d->xmlParser));
_d->valid = false;
+29 -275
View File
@@ -21,7 +21,6 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
#include "HTTPClient.hxx"
#include "HTTPFileRequest.hxx"
@@ -36,16 +35,8 @@
#include <boost/foreach.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/HTTPContentDecode.hxx>
#include <simgear/misc/strutils.hxx>
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
@@ -77,24 +68,17 @@ typedef std::list<Request_ptr> RequestList;
class Client::ClientPrivate
{
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 proxy;
int proxyPort;
std::string proxyAuth;
NetChannelPoller poller;
unsigned int maxConnections;
RequestList pendingRequests;
// connections by host (potentially more than one)
ConnectionDict connections;
SGTimeStamp timeTransferSample;
unsigned int bytesTransferred;
@@ -102,15 +86,13 @@ public:
uint64_t totalBytesDownloaded;
};
#if !defined(ENABLE_CURL)
class Connection : public NetChat
{
public:
Connection(Client* pr, const std::string& conId) :
Connection(Client* pr) :
client(pr),
state(STATE_CLOSED),
port(DEFAULT_HTTP_PORT),
connectionId(conId)
port(DEFAULT_HTTP_PORT)
{
}
@@ -141,11 +123,6 @@ public:
virtual void handleError(int error)
{
const char* errStr = strerror(error);
SG_LOG(SG_IO, SG_WARN, "HTTP Connection handleError:" << error << " ("
<< errStr << ")");
debugDumpRequests();
if (!activeRequest)
{
// connection level failure, eg name lookup or routing
@@ -174,11 +151,6 @@ public:
state = STATE_SOCKET_ERROR;
}
void handleTimeout()
{
handleError(ETIMEDOUT);
}
virtual void handleClose()
{
NetChat::handleClose();
@@ -191,13 +163,6 @@ public:
state = STATE_CLOSED;
responseComplete();
} 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) {
activeRequest->setFailure(500, "server closed connection");
// remove the failed request from sentRequests, so it does
@@ -225,6 +190,19 @@ public:
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)
{
queuedRequests.push_back(r);
@@ -241,7 +219,6 @@ public:
activeRequest->responseStart(buffer);
} catch (sg_exception& e) {
handleError(EIO);
return;
}
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
queuedRequests.pop_front();
sentRequests.push_back(r);
@@ -426,23 +405,21 @@ public:
bool hasIdleTimeout() const
{
if ((state != STATE_IDLE) && (state != STATE_CLOSED)) {
if (state != STATE_IDLE) {
return false;
}
assert(sentRequests.empty());
bool isTimedOut = (idleTime.elapsedMSec() > (1000 * 10)); // 10 seconds
return isTimedOut;
return idleTime.elapsedMSec() > 1000 * 10; // ten seconds
}
bool hasErrorTimeout() const
{
if ((state == STATE_IDLE) || (state == STATE_CLOSED)) {
if (state == STATE_IDLE) {
return false;
}
bool isTimedOut = (idleTime.elapsedMSec() > (1000 * 30)); // 30 seconds
return isTimedOut;
return idleTime.elapsedMSec() > (1000 * 30); // 30 seconds
}
bool hasError() const
@@ -459,37 +436,17 @@ public:
{
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:
bool connectToHost()
{
SG_LOG(SG_IO, SG_DEBUG, "HTTP connecting to " << host << ":" << port);
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;
}
if (connect(host.c_str(), port) != 0) {
SG_LOG(SG_IO, SG_WARN, "HTTP::Connection: connectToHost: connect() failed");
return false;
}
@@ -630,6 +587,7 @@ private:
// notify request after we change state, so this connection is idle
// if completion triggers other requests (which is likely)
// SG_LOG(SG_IO, SG_INFO, "*** responseComplete:" << activeRequest->url());
completedRequest->responseComplete();
client->requestFinished(this);
@@ -663,9 +621,7 @@ private:
RequestList sentRequests;
ContentDecoder _contentDecoder;
std::string connectionId;
};
#endif // of !ENABLE_CURL
Client::Client() :
d(new ClientPrivate)
@@ -678,22 +634,10 @@ Client::Client() :
d->totalBytesDownloaded = 0;
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()
{
#if defined(ENABLE_CURL)
curl_multi_cleanup(d->curlMulti);
#endif
}
void Client::setMaxConnections(unsigned int maxCon)
@@ -703,47 +647,10 @@ void Client::setMaxConnections(unsigned int maxCon)
}
d->maxConnections = maxCon;
#if defined(ENABLE_CURL)
curl_multi_setopt(d->curlMulti, CURLMOPT_MAXCONNECTS, (long) maxCon);
#endif
}
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)) {
SGTimeStamp::sleepForMSec(waitTimeout);
} else {
@@ -789,7 +696,6 @@ void Client::update(int waitTimeout)
makeRequest(req);
}
}
#endif
}
void Client::makeRequest(const Request_ptr& r)
@@ -802,82 +708,6 @@ void Client::makeRequest(const Request_ptr& r)
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 ) {
r->setFailure(EINVAL, "only HTTP protocol is supported");
return;
@@ -935,7 +765,7 @@ void Client::makeRequest(const Request_ptr& r)
// allocate a new connection object
if (!con) {
con = new Connection(this, connectionId);
con = new Connection(this);
con->setServer(host, port);
d->poller.addChannel(con);
d->connections.insert(d->connections.end(),
@@ -943,7 +773,6 @@ void Client::makeRequest(const Request_ptr& r)
}
con->queueRequest(r);
#endif
}
//------------------------------------------------------------------------------
@@ -999,16 +828,12 @@ void Client::setProxy( const std::string& proxy,
bool Client::hasActiveRequests() const
{
#if defined(ENABLE_CURL)
return d->haveActiveRequests;
#else
ConnectionDict::const_iterator it = d->connections.begin();
for (; it != d->connections.end(); ++it) {
if (it->second->isActive()) return true;
}
return false;
#endif
}
void Client::receivedBytes(unsigned int count)
@@ -1048,77 +873,6 @@ uint64_t Client::totalBytesDownloaded() const
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 simgear
-7
View File
@@ -98,14 +98,7 @@ public:
* monitoring
*/
uint64_t totalBytesDownloaded() const;
void debugDumpRequests();
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 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
string_list parts = strutils::split(r, NULL, maxSplit);
if (parts.size() != 3) {
throw sg_io_exception("bad HTTP response:" + r);
throw sg_io_exception("bad HTTP response");
}
_responseVersion = decodeHTTPVersion(parts[0]);
_responseStatus = strutils::to_int(parts[1]);
_responseReason = parts[2];
setReadyState(STATUS_RECEIVED);
}
//------------------------------------------------------------------------------
void Request::responseHeader(const std::string& key, const std::string& value)
{
if( key == "connection" ) {
if( key == "connection" )
_willClose = (value.find("close") != std::string::npos);
} else if (key == "content-length") {
int sz = strutils::to_int(value);
setResponseLength(sz);
}
_responseHeaders[key] = value;
}
@@ -325,7 +319,6 @@ unsigned int Request::responseLength() const
//------------------------------------------------------------------------------
void Request::setFailure(int code, const std::string& reason)
{
SG_LOG(SG_IO, SG_WARN, "HTTP request: set failure:" << code << " reason " << reason);
_responseStatus = code;
_responseReason = reason;
-1
View File
@@ -50,7 +50,6 @@ public:
{
UNSENT = 0,
OPENED,
STATUS_RECEIVED,
HEADERS_RECEIVED,
LOADING,
DONE,
+7 -13
View File
@@ -96,14 +96,14 @@ void SVNDirectory::parseCache()
LineState lineState = LINESTATE_HREF;
std::ifstream file(p.c_str());
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;
}
bool doneSelf = false;
file.getline(href, 1024);
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;
}
@@ -183,7 +183,7 @@ void SVNDirectory::writeCache()
void SVNDirectory::setBaseUrl(const string& url)
{
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;
}
@@ -239,6 +239,7 @@ void SVNDirectory::deleteChildByName(const std::string& nm)
{
DAVResource* child = dav->childWithName(nm);
if (!child) {
// std::cerr << "ZZZ: deleteChildByName: unknown:" << nm << std::endl;
return;
}
@@ -246,24 +247,17 @@ void SVNDirectory::deleteChildByName(const std::string& nm)
if (child->isCollection()) {
Dir d(path);
bool ok = d.remove(true);
if (!ok) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "SVNDirectory::deleteChildByName: failed to remove dir:"
<< nm << " at path:\n\t" << path);
}
d.remove(true);
DirectoryList::iterator it = findChildDir(nm);
if (it != _children.end()) {
SVNDirectory* c = *it;
// std::cout << "YYY: deleting SVNDirectory for:" << nm << std::endl;
delete c;
_children.erase(it);
}
} else {
bool ok = path.remove();
if (!ok) {
SG_LOG(SG_TERRASYNC, SG_ALERT, "SVNDirectory::deleteChildByName: failed to remove path:" << nm
<< " at path:\n\t" << path);
}
path.remove();
}
dav->removeChild(child);
+5 -8
View File
@@ -73,7 +73,7 @@ public:
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() << ")");
isUpdating = false;
status = err;
@@ -120,7 +120,6 @@ namespace { // anonmouse
Request(repo->baseUrl, "PROPFIND"),
_repo(repo)
{
assert(repo);
requestHeader("Depth") = "0";
setBodyData( PROPFIND_REQUEST_BODY,
"application/xml; charset=\"utf-8\"" );
@@ -134,13 +133,11 @@ namespace { // anonmouse
} else if (responseCode() == 404) {
_repo->propFindFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND);
} else {
SG_LOG(SG_TERRASYNC, SG_WARN, "request for:" << url() <<
SG_LOG(SG_IO, SG_WARN, "request for:" << url() <<
" return code " << responseCode());
_repo->propFindFailed(this, SVNRepository::SVN_ERROR_SOCKET);
_repo = NULL;
}
Request::responseHeadersComplete();
}
virtual void onDone()
@@ -231,7 +228,7 @@ protected:
_repo->updateFailed(this, SVNRepository::SVN_ERROR_NOT_FOUND);
_failed = true;
} 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());
_repo->updateFailed(this, SVNRepository::SVN_ERROR_HTTP);
_failed = true;
@@ -331,7 +328,7 @@ void SVNRepository::update()
}
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;
return;
}
@@ -375,7 +372,7 @@ void SVNRepoPrivate::propFindComplete(HTTP::Request* req, DAVCollection* c)
void SVNRepoPrivate::propFindFailed(HTTP::Request *req, SVNRepository::ResultCode err)
{
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;
-12
View File
@@ -227,13 +227,6 @@ void NetChannel::handleAccept (void) {
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.
// (and we (ab-)use ENOENT to mean 'name not found'.
if (error != ENOENT) {
@@ -258,11 +251,6 @@ NetChannelPoller::removeChannel(NetChannel* channel)
assert(channel->poller == this);
channel->poller = NULL;
// portability: MSVC throws assertion failure when empty
if (channels.empty()) {
return;
}
ChannelList::iterator it = channels.begin();
for (; it != channels.end(); ++it) {
if (*it == channel) {
-1
View File
@@ -27,7 +27,6 @@
#include <cstring>
#include <cstdlib>
#include <algorithm>
namespace simgear {
-1
View File
@@ -32,7 +32,6 @@
#include <cstring>
#include <cstdlib> // for atoi
#include <algorithm>
using std::string;
+21 -146
View File
@@ -3,23 +3,15 @@
#include <iostream>
#include <map>
#include <sstream>
#include <errno.h>
#include <boost/algorithm/string/case_conv.hpp>
#include <simgear/simgear_config.h>
#include "HTTPClient.hxx"
#include "HTTPRequest.hxx"
#include <simgear/io/sg_netChat.hxx>
#include <simgear/misc/strutils.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::cerr;
@@ -64,8 +56,7 @@ public:
TestRequest(const std::string& url, const std::string method = "GET") :
HTTP::Request(url, method),
complete(false),
failed(false)
complete(false)
{
}
@@ -91,7 +82,6 @@ protected:
virtual void responseHeader(const string& header, const string& value)
{
Request::responseHeader(header, value);
headers[header] = value;
}
};
@@ -151,7 +141,7 @@ public:
string::size_type colonPos = buffer.find(':');
if (colonPos == string::npos) {
cerr << "test malformed HTTP response header:" << buffer << endl;
cerr << "malformed HTTP response header:" << buffer << endl;
buffer.clear();
return;
}
@@ -187,6 +177,7 @@ public:
void receivedRequestHeaders()
{
state = STATE_IDLE;
if (path == "/test1") {
string contentStr(BODY1);
stringstream d;
@@ -246,7 +237,7 @@ public:
}
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();
@@ -256,28 +247,8 @@ public:
sendErrorResponse(400, true, "bad destination");
}
string credentials = requestHeaders["Proxy-Authorization"];
if (credentials.substr(0, 5) != "Basic") {
// 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
if (requestHeaders["Proxy-Authorization"] != "ABCDEF") {
sendErrorResponse(401, false, "bad auth"); // forbidden
}
sendBody2();
@@ -301,12 +272,6 @@ public:
d << contentStr;
push(d.str().c_str());
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") {
if ((args["foo"] != "abc") || (args["bar"] != "1234") || (args["username"] != "johndoe")) {
sendErrorResponse(400, true, "bad arguments");
@@ -330,16 +295,6 @@ public:
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"]);
setByteCount(requestContentLength);
state = STATE_REQUEST_BODY;
} else {
sendErrorResponse(404, false, "");
}
@@ -368,34 +323,9 @@ public:
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_put") {
std::cerr << "sending PUT response" << std::endl;
COMPARE(buffer, BODY3);
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);
cerr << "sent 204 response ok" << endl;
}
buffer.clear();
}
void sendBody2()
@@ -411,8 +341,6 @@ public:
void sendErrorResponse(int code, bool close, string content)
{
cerr << "sending error " << code << " for " << path << endl;
cerr << "\tcontent:" << content << endl;
stringstream headerData;
headerData << "HTTP/1.1 " << code << " " << reasonForCode(code) << "\r\n";
headerData << "Content-Length:" << content.size() << "\r\n";
@@ -429,10 +357,8 @@ public:
{
switch (code) {
case 200: return "OK";
case 201: return "Created";
case 204: return "no content";
case 404: return "not found";
case 407: return "proxy authentication required";
default: return "unknown code";
}
}
@@ -453,8 +379,6 @@ class TestServer : public NetChannel
public:
TestServer()
{
Socket::initSockets();
open();
bind(NULL, 2000); // localhost, any port
listen(5);
@@ -490,14 +414,14 @@ TestServer testServer;
void waitForComplete(HTTP::Client* cl, TestRequest* tr)
{
SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 10000) {
while (start.elapsedMSec() < 1000) {
cl->update();
testServer.poll();
if (tr->complete) {
return;
}
SGTimeStamp::sleepForMSec(15);
SGTimeStamp::sleepForMSec(1);
}
cerr << "timed out" << endl;
@@ -506,14 +430,14 @@ void waitForComplete(HTTP::Client* cl, TestRequest* tr)
void waitForFailed(HTTP::Client* cl, TestRequest* tr)
{
SGTimeStamp start(SGTimeStamp::now());
while (start.elapsedMSec() < 10000) {
while (start.elapsedMSec() < 1000) {
cl->update();
testServer.poll();
if (tr->failed) {
return;
}
SGTimeStamp::sleepForMSec(15);
SGTimeStamp::sleepForMSec(1);
}
cerr << "timed out waiting for failure" << endl;
@@ -521,7 +445,6 @@ void waitForFailed(HTTP::Client* cl, TestRequest* tr)
int main(int argc, char* argv[])
{
sglog().setLogLevels( SG_ALL, SG_INFO );
HTTP::Client cl;
// 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);
}
cerr << "done args" << endl;
{
TestRequest* tr = new TestRequest("http://localhost:2000/test_headers");
HTTP::Request_ptr own(tr);
@@ -607,7 +532,7 @@ int main(int argc, char* argv[])
COMPARE(tr->bodyData, string(body2, body2Size));
}
cerr << "testing chunked transfer encoding" << endl;
cerr << "testing chunked" << endl;
{
TestRequest* tr = new TestRequest("http://localhost:2000/testchunked");
HTTP::Request_ptr own(tr);
@@ -668,40 +593,15 @@ int main(int argc, char* argv[])
}
cout << "done3" << endl;
// test connectToHost failure
/*
{
TestRequest* tr = new TestRequest("http://not.found/something");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
waitForFailed(&cl, tr);
#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);
waitForFailed(tr);
COMPARE(tr->responseCode(), -1);
}
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
{
cl.setProxy("localhost", 2000);
@@ -714,9 +614,8 @@ cout << "testing proxy close" << endl;
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");
HTTP::Request_ptr own(tr);
cl.makeRequest(tr);
@@ -725,10 +624,9 @@ cout << "testing proxy close" << endl;
COMPARE(tr->responseBytesReceived(), body2Size);
COMPARE(tr->bodyData, string(body2, body2Size));
}
#endif
// 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
{
cout << "testing POST" << endl;
cout << "POST" << endl;
TestRequest* tr = new TestRequest("http://localhost:2000/test_post?foo=abc&bar=1234&username=johndoe", "POST");
tr->setBodyData("", "application/x-www-form-urlencoded");
@@ -801,29 +699,6 @@ cout << "testing proxy close" << endl;
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
{
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.
// 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)
// Also removed unused variables and corrected earth radii constants
// to the values for WGS84 and WMM2005.
@@ -36,20 +36,6 @@
//
// 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
// potential up to twelfth order, together with its time variation, as
@@ -93,7 +79,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <math.h>
#include <simgear/constants.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 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},
{-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},
{-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},
{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},
{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},
{-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},
{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},
{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},
{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},
{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},
{-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},
{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.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},
{-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},
{-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},
{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},
{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},
{-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},
{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},
{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.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.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},
{-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},
{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.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, 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, -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, -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, 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, 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, -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, -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, 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, -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, 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, -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, -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, 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, -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, -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, 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, 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.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, -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, 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, -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, 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.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, -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},
{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.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},
{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, 0.8, -9.2, 4.0, -4.2, 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},
{-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.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.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.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.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.1, 0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.1, -0.1, 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},
{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},
{-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},
{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},
{-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},
{-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.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.1, -0.3, 1.1, 0.6, 0.5, -0.4, 0.6, 0.0, 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.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.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},
};
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, -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, -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, 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, -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, 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, -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.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.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.2, 0.1, 0.1, 0.0, -0.2, 0.4, 0.3, 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.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.1, 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, -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, 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, 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.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.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.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.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.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.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},
};
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 */
int n,m;
/* reference date for current model is 1 januari 2015 */
long date0_wmm2015 = yymmdd_to_julian_days(15,1,1);
/* reference date for current model is 1 januari 2005 */
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 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
achieved by adjusting the coefficients at time t0 for linear secular variation */
/* WMM2015 */
yearfrac = (dat - date0_wmm2015) / 365.25;
/* WMM2005 */
yearfrac = (dat - date0_wmm2005) / 365.25;
for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2015[n][m] + yearfrac * gtnm_wmm2015[n][m];
hnm[n][m] = hnm_wmm2015[n][m] + yearfrac * htnm_wmm2015[n][m];
gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[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 */
int n,m;
/* 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;
@@ -421,12 +407,12 @@ double SGMagVarOrig( double lat, double lon, double h, long dat, double* field )
}
/* compute gnm, hnm at dat */
/* WMM2015 */
yearfrac = (dat - date0_wmm2015) / 365.25;
/* WMM2005 */
yearfrac = (dat - date0_wmm2005) / 365.25;
for ( n = 1; n <= nmax; n++ ) {
for ( m = 0; m <= nmax; m++ ) {
gnm[n][m] = gnm_wmm2015[n][m] + yearfrac * gtnm_wmm2015[n][m];
hnm[n][m] = hnm_wmm2015[n][m] + yearfrac * htnm_wmm2015[n][m];
gnm[n][m] = gnm_wmm2005[n][m] + yearfrac * gtnm_wmm2005[n][m];
hnm[n][m] = hnm_wmm2005[n][m] + yearfrac * htnm_wmm2005[n][m];
}
}
+1 -1
View File
@@ -26,7 +26,7 @@
#endif
#include <cmath>
#include <math.h>
#include <simgear/magvar/magvar.hxx>
#include <simgear/math/SGMath.hxx>
+3 -3
View File
@@ -1,8 +1,8 @@
/* 2/14/00 fixed help message- dip angle (down positive), variation (E positive) */
#include <stdio.h>
#include <stdlib.h>
#include <cmath>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <simgear/constants.h>
+1 -1
View File
@@ -154,7 +154,7 @@ public:
static bool isNaN(const T& v)
{
#ifdef HAVE_ISNAN
return (isnan(v) != 0);
return isnan(v);
#elif defined HAVE_STD_ISNAN
return std::isnan(v);
#else
+1 -1
View File
@@ -59,7 +59,7 @@ namespace simgear
}
void setMaxSubdiv( size_t aMaxSubdiv ) { mMaxSubdiv = aMaxSubdiv; }
size_t getMaxSubdiv() const { return mMaxSubdiv; }
void getMaxSubdiv() const { return mMaxSubdiv; }
PointList &pointList() { return mPointList; }
const PointList &pointList() const { return mPointList; }
+1 -1
View File
@@ -67,7 +67,7 @@ SGInterpTable::SGInterpTable( const std::string& file )
while ( in ) {
double ind, dep;
in >> ind >> dep;
in >> std::skipws;
in >> skipws;
_table[ind] = dep;
}
}
-4
View File
@@ -37,10 +37,6 @@ set(SOURCES
gzcontainerfile.cxx
)
if (WINDOWS)
list(APPEND HEADERS sgversionhelpers.hxx)
endif()
if (APPLE)
list(APPEND SOURCES CocoaHelpers.mm)
endif()
-4
View File
@@ -141,11 +141,7 @@ int main(int argc, char* argv[])
// add
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"));
#endif
// concat
SGPath pd = pb;
-1
View File
@@ -382,7 +382,6 @@ bool Dir::remove(bool recursive)
if (recursive) {
if (!removeChildren()) {
SG_LOG(SG_IO, SG_WARN, "Dir at:" << _path << " failed to remove children");
return false;
}
} // of recursive deletion
+31 -94
View File
@@ -56,10 +56,7 @@ static const char sgSearchPathSep = ':';
#endif
#ifdef _WIN32
#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"
#include <ShlObj.h> // for CSIDL
static SGPath pathForCSIDL(int csidl, const SGPath& def)
{
@@ -83,42 +80,6 @@ static SGPath pathForCSIDL(int csidl, const SGPath& 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__
// defined in CocoaHelpers.mm
@@ -743,35 +704,20 @@ SGPath SGPath::standardLocation(StandardLocation type, const SGPath& def)
{
case HOME:
return home(def);
#ifdef _WIN32
case DESKTOP:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Desktop, def);
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
case DOWNLOADS:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Downloads, def);
if (!def.isNull())
return def;
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
// TODO use KnownFolders
// http://msdn.microsoft.com/en-us/library/bb776911%28v=vs.85%29.aspx
if( !def.isNull() )
return def;
return pathForCSIDL(CSIDL_DESKTOPDIRECTORY, def);
case DOCUMENTS:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Documents, def);
return pathForCSIDL(CSIDL_MYDOCUMENTS, def);
return pathForCSIDL(CSIDL_MYDOCUMENTS, def);
case PICTURES:
if (IsWindowsVistaOrGreater())
return pathForKnownFolder(FOLDERID_Pictures, def);
return pathForCSIDL(CSIDL_MYPICTURES, def);
return pathForCSIDL(CSIDL_MYPICTURES, def);
#elif __APPLE__
// 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)
@@ -810,15 +756,20 @@ SGPath SGPath::fromEnv(const char* name, const SGPath& def)
return def;
}
#ifdef _WIN32
//------------------------------------------------------------------------------
SGPath SGPath::home(const SGPath& def)
{
#ifdef _WIN32
return fromEnv("USERPROFILE", def);
#else
return fromEnv("HOME", def);
#endif
// TODO
return def;
}
#else
//------------------------------------------------------------------------------
SGPath SGPath::home(const SGPath& def)
{
return fromEnv("HOME", def);
}
#endif
//------------------------------------------------------------------------------
SGPath SGPath::desktop(const SGPath& def)
@@ -835,39 +786,25 @@ SGPath SGPath::documents(const SGPath& def)
//------------------------------------------------------------------------------
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
char *buf = _fullpath( NULL, path.c_str(), _MAX_PATH );
#else
#else
// POSIX
char* buf = ::realpath(path.c_str(), NULL);
#endif
if (!buf) // File does not exist: return the realpath it would have if created now
// (needed for fgValidatePath security)
#endif
if (!buf)
{
if (path.empty()) {
return SGPath(".").realpath(); // current directory
}
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
SG_LOG(SG_IO, SG_ALERT, "ERROR: The path '" << path << "' does not exist in the file system.");
return path;
}
std::string p(buf);
free(buf);
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 <cstring>
#include <sstream>
#include <algorithm>
#include "strutils.hxx"
+1 -1
View File
@@ -4,7 +4,6 @@ include (SimGearComponent)
set(HEADERS
naref.h
nasal.h
iolib.h
)
set(SOURCES
@@ -27,6 +26,7 @@ set(SOURCES
vector.c
code.h
data.h
iolib.h
parse.h
)
+8
View File
@@ -66,6 +66,14 @@ namespace nasal
void GhostMetadata::addDerived(const GhostMetadata* 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)("0x055"), 0x55);
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 )
-6
View File
@@ -142,9 +142,6 @@ naRef naIOGhost(naContext c, FILE* f)
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)
{
FILE* f;
@@ -155,7 +152,6 @@ static naRef f_open(naContext c, naRef me, int argc, naRef* args)
if(!f) naRuntimeError(c, strerror(errno));
return naIOGhost(c, f);
}
#endif
// frees buffer before tossing an error
static int getcguard(naContext ctx, FILE* f, void* buf)
@@ -248,9 +244,7 @@ static naCFuncItem funcs[] = {
{ "seek", f_seek },
{ "tell", f_tell },
{ "flush", f_flush },
#if SG_NASAL_UNRESTRICTED_OPEN
{ "open", f_open },
#endif
{ "readln", f_readln },
{ "stat", f_stat },
{ 0 }
+1 -6
View File
@@ -1,8 +1,5 @@
#ifndef _IOLIB_H
#define _IOLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#include "nasal.h"
@@ -36,7 +33,5 @@ extern struct naIOType naStdIOType;
// Defined in iolib.c, there is no "library" header to put this in
naRef naIOGhost(naContext c, FILE* f);
#ifdef __cplusplus
} // extern "C"
#endif
#endif // _IOLIB_H
+15 -18
View File
@@ -1,31 +1,28 @@
#ifndef _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) || \
defined(__powerpc64__)
/* NASAL_NAN64 mode requires 64 bit pointers that only use the
* lower 48 bits; Win64 and Irix should work with this too, but
* have not been tested */
/* Win64 and Irix should work with this too, but have not been
* tested */
# define NASAL_NAN64
#elif defined(__BYTE_ORDER__)
/* 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) || \
#elif defined(_M_IX86) || defined(i386) || defined(__x86_64) || \
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
#elif defined(__sparc) || defined(__ARMEB__) || \
defined(__hppa__) || defined(__s390__) || defined(__s390x__)
#elif defined(__sparc) || defined(__ppc__) || defined(__PPC) || \
defined (__powerpc__) || defined (__powerpc64__) || defined (__alpha__) || \
defined(__mips) || defined(__ARMEB__) || \
defined(__hppa__) || defined(__s390__) || defined(__s390x__) || \
(defined(__sh__) && !defined(__LITTLE_ENDIAN__))
# define NASAL_BE
#else
# error Unknown endianness
# error Unrecognized CPU architecture
#endif
typedef union {
-12
View File
@@ -26,15 +26,3 @@ if(ENABLE_PKGUTIL)
add_executable(sg_pkgutil pkgutil.cxx)
target_link_libraries(sg_pkgutil ${TEST_LIBS})
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)
+62 -176
View File
@@ -36,36 +36,7 @@ namespace simgear {
namespace pkg {
bool checkVersion(const std::string& aVersion, SGPropertyNode_ptr props)
{
BOOST_FOREACH(SGPropertyNode* v, props->getChildren("version")) {
std::string s(v->getStringValue());
if (s== aVersion) {
return true;
}
// allow 3.5.* to match any of 3.5.0, 3.5.1rc1, 3.5.11 or so on
if (strutils::ends_with(s, ".*")) {
size_t lastDot = aVersion.rfind('.');
std::string ver = aVersion.substr(0, lastDot);
if (ver == s.substr(0, s.length() - 2)) {
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();
}
CatalogList static_catalogs;
//////////////////////////////////////////////////////////////////////////////
@@ -76,8 +47,6 @@ public:
HTTP::Request(aUrl),
m_owner(aOwner)
{
// refreshing
m_owner->changeStatus(Delegate::STATUS_IN_PROGRESS);
}
protected:
@@ -89,13 +58,8 @@ protected:
virtual void onDone()
{
if (responseCode() != 200) {
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url()
<< "\n\t" << responseCode());
if (responseCode() == 404) {
code = Delegate::FAIL_NOT_FOUND;
}
m_owner->refreshComplete(code);
SG_LOG(SG_GENERAL, SG_ALERT, "catalog download failure:" << m_owner->url());
m_owner->refreshComplete(Delegate::FAIL_DOWNLOAD);
return;
}
@@ -110,35 +74,13 @@ protected:
return;
}
if (m_owner->root()->catalogVersion() != props->getIntValue("catalog-version")) {
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());
std::string ver(m_owner->root()->catalogVersion());
if (!checkVersion(ver, props)) {
SG_LOG(SG_GENERAL, SG_WARN, "downloaded catalog " << m_owner->url() << ", version mismatch:\n\t"
<< 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;
} // of version check failed
}
// cache the catalog data, now we have a valid install root
Dir d(m_owner->installRoot());
@@ -150,10 +92,19 @@ protected:
time(&m_owner->m_retrievedTime);
m_owner->writeTimestamp();
m_owner->refreshComplete(Delegate::STATUS_REFRESHED);
m_owner->refreshComplete(Delegate::FAIL_SUCCESS);
}
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;
std::string m_buffer;
@@ -161,22 +112,31 @@ private:
//////////////////////////////////////////////////////////////////////////////
CatalogList Catalog::allCatalogs()
{
return static_catalogs;
}
Catalog::Catalog(Root *aRoot) :
m_root(aRoot),
m_status(Delegate::FAIL_UNKNOWN),
m_retrievedTime(0)
{
static_catalogs.push_back(this);
}
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 c = new Catalog(aRoot);
c->m_url = aUrl;
c->refresh();
Downloader* dl = new Downloader(c, aUrl);
aRoot->makeHTTPRequest(dl);
return c;
}
@@ -196,22 +156,10 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
return NULL;
}
if (!checkVersion(aRoot->applicationVersion(), props)) {
std::string redirect = redirectUrlForVersion(aRoot->applicationVersion(), props);
if (!redirect.empty()) {
SG_LOG(SG_GENERAL, SG_WARN, "catalog at " << aPath << ", version mismatch:\n\t"
<< "redirecting to alternate URL:" << redirect);
CatalogRef c = Catalog::createFromUrl(aRoot, redirect);
c->m_installRoot = aPath;
return c;
} else {
SG_LOG(SG_GENERAL, SG_WARN, "skipping catalog at " << aPath << ", version mismatch:\n\t"
if (props->getStringValue("version") != aRoot->catalogVersion()) {
SG_LOG(SG_GENERAL, SG_WARN, "skipping catalog at " << aPath << ", version mismatch:\n\t"
<< props->getStringValue("version") << " vs required " << aRoot->catalogVersion());
return NULL;
}
} else {
SG_LOG(SG_GENERAL, SG_INFO, "creating catalog from:" << aPath);
return NULL;
}
CatalogRef c = new Catalog(aRoot);
@@ -219,39 +167,9 @@ CatalogRef Catalog::createFromPath(Root* aRoot, const SGPath& aPath)
c->parseProps(props);
c->parseTimestamp();
// parsed XML ok, mark status as valid
c->changeStatus(Delegate::STATUS_SUCCESS);
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&
Catalog::packages() const
{
@@ -298,30 +216,29 @@ Catalog::installedPackages() const
return r;
}
void Catalog::refresh()
InstallRef Catalog::installForPackage(PackageRef pkg) const
{
if (m_refreshRequest.valid()) {
// refresh in progress
return;
PackageInstallDict::const_iterator it = m_installed.find(pkg);
if (it == m_installed.end()) {
// check if it exists on disk, create
SGPath p(pkg->pathOnDisk());
if (p.exists()) {
return Install::createFromPath(p, CatalogRef(const_cast<Catalog*>(this)));
}
return NULL;
}
Downloader* dl = new Downloader(this, url());
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) {}
bool operator()(const PackageRef& ref) const
{
return ref->id() == m_id;
}
std::string m_id;
};
Downloader* dl = new Downloader(this, url());
m_root->makeHTTPRequest(dl);
m_root->catalogRefreshBegin(this);
}
void Catalog::parseProps(const SGPropertyNode* aProps)
{
@@ -336,14 +253,8 @@ void Catalog::parseProps(const SGPropertyNode* aProps)
for (int i = 0; i < nChildren; i++) {
const SGPropertyNode* pkgProps = aProps->getChild(i);
if (strcmp(pkgProps->getName(), "package") == 0) {
// can't use getPackageById here becuase the variant dict isn't
// built yet. Instead we need to look at m_packages directly.
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;
PackageRef p = getPackageById(pkgProps->getStringValue("id"));
if (p) {
// existing package
p->updateFromProps(pkgProps);
orphans.erase(p); // not an orphan
@@ -401,23 +312,11 @@ PackageRef Catalog::getPackageById(const std::string& aId) const
// works as expected.
PackageWeakMap::const_iterator it = m_variantDict.find(aId);
if (it == m_variantDict.end())
return PackageRef();
return NULL;
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
{
return m_props->getStringValue("id");
@@ -428,11 +327,6 @@ std::string Catalog::url() const
return m_url;
}
std::string Catalog::name() const
{
return getLocalisedString(m_props, "name");
}
std::string Catalog::description() const
{
return getLocalisedString(m_props, "description");
@@ -475,10 +369,6 @@ bool Catalog::needsRefresh() const
std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const
{
if (!aRoot) {
return std::string();
}
if (aRoot->hasChild(m_root->getLocale())) {
const SGPropertyNode* localeRoot = aRoot->getChild(m_root->getLocale().c_str());
if (localeRoot->hasChild(aName)) {
@@ -489,31 +379,27 @@ std::string Catalog::getLocalisedString(const SGPropertyNode* aRoot, const char*
return aRoot->getStringValue(aName);
}
void Catalog::refreshComplete(Delegate::StatusCode aReason)
void Catalog::refreshComplete(Delegate::FailureCode aReason)
{
changeStatus(aReason);
m_refreshRequest.reset();
m_root->catalogRefreshComplete(this, aReason);
}
void Catalog::changeStatus(Delegate::StatusCode newStatus)
void Catalog::registerInstall(Install* ins)
{
if (m_status == newStatus) {
return;
}
if (!ins || ins->package()->catalog() != this) {
return;
}
m_status = newStatus;
m_root->catalogRefreshStatus(this, newStatus);
m_statusCallbacks(this);
m_installed[ins->package()] = ins;
}
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
{
return m_status;
m_installed.erase(ins->package());
}
} // of namespace pkg
+12 -30
View File
@@ -22,15 +22,11 @@
#include <ctime>
#include <map>
#include <boost/bind.hpp>
#include <simgear/misc/sg_path.hxx>
#include <simgear/props/props.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/structure/function_list.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <simgear/package/Delegate.hxx>
@@ -64,14 +60,11 @@ public:
static CatalogRef createFromPath(Root* aRoot, const SGPath& aPath);
static CatalogList allCatalogs();
Root* root() const
{ return m_root;};
/**
* uninstall this catalog entirely, including all installed packages
*/
bool uninstall();
/**
* perform a refresh of the catalog contents
*/
@@ -106,13 +99,11 @@ public:
std::string url() const;
std::string name() const;
std::string description() 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
@@ -126,41 +117,29 @@ public:
* access the raw property data in the catalog
*/
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:
Catalog(Root* aRoot);
class Downloader;
friend class Downloader;
friend class Install;
void registerInstall(Install* ins);
void unregisterInstall(Install* ins);
void parseProps(const SGPropertyNode* aProps);
void refreshComplete(Delegate::StatusCode aReason);
void refreshComplete(Delegate::FailureCode aReason);
void parseTimestamp();
void writeTimestamp();
std::string getLocalisedString(const SGPropertyNode* aRoot, const char* aName) const;
void changeStatus(Delegate::StatusCode newStatus);
Root* m_root;
SGPropertyNode_ptr m_props;
SGPath m_installRoot;
std::string m_url;
Delegate::StatusCode m_status;
HTTP::Request_ptr m_refreshRequest;
PackageList m_packages;
time_t m_retrievedTime;
@@ -168,7 +147,10 @@ private:
typedef std::map<std::string, Package*> PackageWeakMap;
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
-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;
}
+20 -28
View File
@@ -18,9 +18,6 @@
#ifndef SG_PACKAGE_DELEGATE_HXX
#define SG_PACKAGE_DELEGATE_HXX
#include <simgear/misc/stdint.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
namespace simgear
{
@@ -30,9 +27,6 @@ namespace pkg
class Install;
class Catalog;
typedef SGSharedPtr<Catalog> CatalogRef;
typedef SGSharedPtr<Install> InstallRef;
/**
* package delegate is the mechanism to discover progress / completion /
* errors in packaging steps asynchronously.
@@ -41,40 +35,38 @@ class Delegate
{
public:
typedef enum {
STATUS_SUCCESS = 0,
FAIL_SUCCESS = 0, ///< not a failure :)
FAIL_UNKNOWN = 1,
STATUS_IN_PROGRESS, ///< downloading/installation in progress
FAIL_CHECKSUM, ///< package MD5 verificstion failed
FAIL_DOWNLOAD, ///< network issue
FAIL_EXTRACT, ///< package archive failed to extract cleanly
FAIL_IN_PROGRESS, ///< downloading/installation in progress (not a failure :P)
FAIL_CHECKSUM, ///< package MD5 verificstion failed
FAIL_DOWNLOAD, ///< network issue
FAIL_EXTRACT, ///< package archive failed to extract cleanly
FAIL_FILESYSTEM, ///< unknown filesystem error occurred
FAIL_VERSION, ///< version check mismatch
FAIL_NOT_FOUND, ///< package URL returned a 404
STATUS_REFRESHED,
USER_CANCELLED
} StatusCode;
FAIL_VERSION ///< version check mismatch
} FailureCode;
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
* If catalog is null, this means /all/ catalogs have been refreshed
* emitted when a catalog fails to refresh, due to a network issue or
* 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 installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal) = 0;
virtual void finishInstall(InstallRef aInstall, StatusCode aReason) = 0;
virtual void startInstall(Install* aInstall) = 0;
virtual void installProgress(Install* aInstall, unsigned int aBytes, unsigned int aTotal) = 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,
size_t lenth, const uint8_t* bytes) {}
virtual void failedInstall(Install* aInstall, FailureCode aReason) = 0;
};
} // of namespace pkg
+35 -169
View File
@@ -24,7 +24,6 @@
#include <simgear/package/md5.h>
#include <simgear/structure/exception.hxx>
#include <simgear/props/props_io.hxx>
#include <simgear/package/Catalog.hxx>
#include <simgear/package/Package.hxx>
#include <simgear/package/Root.hxx>
@@ -46,8 +45,7 @@ class Install::PackageArchiveDownloader : public HTTP::Request
public:
PackageArchiveDownloader(InstallRef aOwner) :
HTTP::Request("" /* dummy URL */),
m_owner(aOwner),
m_downloaded(0)
m_owner(aOwner)
{
m_urls = m_owner->package()->downloadUrls();
if (m_urls.empty()) {
@@ -57,39 +55,10 @@ public:
// TODO randomise order of m_urls
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:
virtual std::string url() const
{
@@ -98,8 +67,6 @@ protected:
virtual void responseHeadersComplete()
{
Request::responseHeadersComplete();
Dir d(m_extractPath);
d.create(0755);
@@ -112,21 +79,14 @@ protected:
m_buffer += std::string(s, n);
SG_MD5Update(&m_md5, (unsigned char*) s, n);
m_downloaded = m_buffer.size();
m_owner->installProgress(m_buffer.size(), responseLength());
}
virtual void onDone()
{
if (responseCode() != 200) {
SG_LOG(SG_GENERAL, SG_ALERT, "download failure:" << responseCode() <<
"\n\t" << url());
Delegate::StatusCode code = Delegate::FAIL_DOWNLOAD;
if (responseCode() == 404) {
code = Delegate::FAIL_NOT_FOUND;
}
doFailure(code);
SG_LOG(SG_GENERAL, SG_ALERT, "download failure");
doFailure(Delegate::FAIL_DOWNLOAD);
return;
}
@@ -151,16 +111,13 @@ protected:
}
if (m_owner->path().exists()) {
//std::cout << "removing existing path" << std::endl;
Dir destDir(m_owner->path());
destDir.remove(true /* recursive */);
}
// build a path like /path/to/packages/org.some.catalog/Aircraft/extract_xxxx/MyAircraftDir
SGPath extractedPath = m_extractPath;
extractedPath.append(m_owner->package()->dirName());
// rename it to path/to/packages/org.some.catalog/Aircraft/MyAircraftDir
bool ok = extractedPath.rename(m_owner->path());
m_extractPath.append(m_owner->package()->id());
bool ok = m_extractPath.rename(m_owner->path());
if (!ok) {
doFailure(Delegate::FAIL_FILESYSTEM);
return;
@@ -168,18 +125,7 @@ protected:
m_owner->m_revision = m_owner->package()->revision();
m_owner->writeRevisionFile();
m_owner->m_download.reset(); // so isDownloading reports false
m_owner->installResult(Delegate::STATUS_SUCCESS);
}
virtual void onFail()
{
if (responseCode() == -1) {
doFailure(Delegate::USER_CANCELLED);
} else {
doFailure(Delegate::FAIL_DOWNLOAD);
}
m_owner->installResult(Delegate::FAIL_SUCCESS);
}
private:
@@ -282,16 +228,19 @@ private:
return result;
}
void doFailure(Delegate::StatusCode aReason)
void doFailure(Delegate::FailureCode aReason)
{
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
m_owner->m_download.reset(); // ensure we get cleaned up
m_owner->installResult(aReason);
std::cout << "retrying download" << std::endl;
m_urls.erase(m_urls.begin()); // pop first URL
}
InstallRef m_owner;
@@ -299,29 +248,30 @@ private:
SG_MD5_CTX m_md5;
std::string m_buffer;
SGPath m_extractPath;
size_t m_downloaded;
};
////////////////////////////////////////////////////////////////////
Install::Install(PackageRef aPkg, const SGPath& aPath) :
m_package(aPkg),
m_path(aPath),
m_status(Delegate::STATUS_IN_PROGRESS)
m_download(NULL),
_status(Delegate::FAIL_IN_PROGRESS)
{
parseRevision();
m_package->catalog()->root()->registerInstall(this);
m_package->catalog()->registerInstall(this);
}
Install::~Install()
{
m_package->catalog()->unregisterInstall(this);
}
InstallRef Install::createFromPath(const SGPath& aPath, CatalogRef aCat)
{
std::string path = aPath.file();
PackageRef pkg = aCat->getPackageByPath(path);
std::string id = aPath.file();
PackageRef pkg = aCat->getPackageById(id);
if (!pkg)
throw sg_exception("no package with path:" + path);
throw sg_exception("no package with id:" + id);
return new Install(pkg, aPath);
}
@@ -363,102 +313,17 @@ void Install::startUpdate()
m_package->catalog()->root()->startInstall(this);
}
bool Install::uninstall()
void Install::uninstall()
{
Dir d(m_path);
if (!d.remove(true)) {
SG_LOG(SG_GENERAL, SG_ALERT, "package uninstall failed: couldn't remove path " << m_path);
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;
d.remove(true);
m_package->catalog()->unregisterInstall(this);
}
//------------------------------------------------------------------------------
Install* Install::done(const Callback& cb)
{
if( m_status == Delegate::STATUS_SUCCESS )
if( _status == Delegate::FAIL_SUCCESS )
cb(this);
else
_cb_done.push_back(cb);
@@ -469,8 +334,8 @@ Install* Install::done(const Callback& cb)
//------------------------------------------------------------------------------
Install* Install::fail(const Callback& cb)
{
if( m_status != Delegate::STATUS_SUCCESS
&& m_status != Delegate::STATUS_IN_PROGRESS )
if( _status != Delegate::FAIL_SUCCESS
&& _status != Delegate::FAIL_IN_PROGRESS )
cb(this);
else
_cb_fail.push_back(cb);
@@ -481,7 +346,7 @@ Install* Install::fail(const Callback& cb)
//------------------------------------------------------------------------------
Install* Install::always(const Callback& cb)
{
if( m_status != Delegate::STATUS_IN_PROGRESS )
if( _status != Delegate::FAIL_IN_PROGRESS )
cb(this);
else
_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::STATUS_SUCCESS) {
if (aReason == Delegate::FAIL_SUCCESS) {
m_package->catalog()->root()->finishInstall(this);
_cb_done(this);
} else {
m_package->catalog()->root()->failedInstall(this, aReason);
_cb_fail(this);
}
+4 -33
View File
@@ -21,13 +21,11 @@
#include <vector>
#include <simgear/misc/sg_path.hxx>
#include <simgear/misc/sg_dir.hxx>
#include <simgear/package/Delegate.hxx>
#include <simgear/structure/function_list.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
#include <simgear/io/HTTPRequest.hxx>
#include <boost/bind.hpp>
@@ -76,34 +74,7 @@ public:
void startUpdate();
bool 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;
void uninstall();
/**
* Set the handler to be called when the installation successfully
@@ -174,16 +145,16 @@ private:
void parseRevision();
void writeRevisionFile();
void installResult(Delegate::StatusCode aReason);
void installResult(Delegate::FailureCode aReason);
void installProgress(unsigned int aBytes, unsigned int aTotal);
PackageRef m_package;
unsigned int m_revision; ///< revision 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,
_cb_fail,
+3 -65
View File
@@ -117,7 +117,7 @@ SGPath Package::pathOnDisk() const
{
SGPath p(m_catalog->installRoot());
p.append("Aircraft");
p.append(dirName());
p.append(id());
return p;
}
@@ -139,12 +139,7 @@ InstallRef Package::install()
InstallRef Package::existingInstall(const InstallCallback& cb) const
{
InstallRef install;
try {
install = m_catalog->root()->existingInstallForPackage(const_cast<Package*>(this));
} catch (std::exception& e) {
return InstallRef();
}
InstallRef install = m_catalog->installForPackage(const_cast<Package*>(this));
if( cb )
{
@@ -167,30 +162,13 @@ std::string Package::qualifiedId() const
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
{
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
{
if (!m_props) {
return 0;
}
return m_props->getIntValue("revision");
}
@@ -209,11 +187,6 @@ std::string Package::description() const
return getLocalisedProp("description");
}
string_set Package::tags() const
{
return m_tags;
}
SGPropertyNode* Package::properties() const
{
return m_props.ptr();
@@ -222,36 +195,15 @@ SGPropertyNode* Package::properties() const
string_list Package::thumbnailUrls() const
{
string_list r;
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("thumbnail")) {
r.push_back(dl->getStringValue());
}
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 r;
if (!m_props) {
return r;
}
BOOST_FOREACH(SGPropertyNode* dl, m_props->getChildren("url")) {
r.push_back(dl->getStringValue());
}
@@ -286,7 +238,7 @@ PackageList Package::dependencies() const
// prefer local hangar package if possible, in case someone does something
// 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);
if (!depPkg) {
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());
}
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 simgear
-21
View File
@@ -76,11 +76,6 @@ public:
*/
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,
* 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 unsigned int vIndex) const;
/**
* syntactic sugar to get the localised description
*/
@@ -120,8 +113,6 @@ public:
bool matches(const SGPropertyNode* aFilter) const;
string_set tags() const;
/**
* download URLs for the package
*/
@@ -129,28 +120,16 @@ public:
string_list thumbnailUrls() const;
/**
* thumbnail file paths within the package on disk
*/
string_list thumbnails() const;
/**
* Packages we depend upon.
* If the dependency list cannot be satisifed for some reason,
* this will raise an sg_exception.
*/
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:
SGPath pathOnDisk() const;
friend class Catalog;
friend class Root;
Package(const SGPropertyNode* aProps, CatalogRef aCatalog);
+40 -293
View File
@@ -38,158 +38,31 @@ namespace simgear {
namespace pkg {
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
{
public:
RootPrivate() :
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;
std::string locale;
HTTP::Client* http;
CatalogDict catalogs;
unsigned int maxAgeSeconds;
Delegate* delegate;
std::string version;
std::set<CatalogRef> refreshing;
typedef std::deque<InstallRef> UpdateDeque;
UpdateDeque updateDeque;
std::deque<InstallRef> updateDeque;
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
{
return d->path;
@@ -253,12 +126,7 @@ Root::~Root()
}
int Root::catalogVersion() const
{
return 4;
}
std::string Root::applicationVersion() const
std::string Root::catalogVersion() const
{
return d->version;
}
@@ -312,20 +180,6 @@ CatalogList Root::catalogs() const
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
Root::packagesMatching(const SGPropertyNode* aFilter) const
{
@@ -356,34 +210,17 @@ Root::packagesNeedingUpdate() const
void Root::refresh(bool aForce)
{
bool didStartAny = false;
CatalogDict::iterator it = d->catalogs.begin();
for (; it != d->catalogs.end(); ++it) {
if (aForce || it->second->needsRefresh()) {
it->second->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);
}
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);
d->delegate = aDelegate;
}
void Root::setLocale(const std::string& aLocale)
@@ -417,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)
{
d->fireStartInstall(aInstall);
if (d->delegate) {
d->delegate->startInstall(aInstall.ptr());
}
}
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)
@@ -447,46 +281,39 @@ void Root::startNext(InstallRef aCurrent)
}
}
void Root::finishInstall(InstallRef aInstall, Delegate::StatusCode aReason)
void Root::finishInstall(InstallRef aInstall)
{
if (aReason != Delegate::STATUS_SUCCESS) {
SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:"
<< aInstall->package()->id() << ":" << aReason);
if (d->delegate) {
d->delegate->finishInstall(aInstall.ptr());
}
// order matters here, so a call to 'isQueued' from a finish-install
// callback returns false, not true
startNext(aInstall);
d->fireFinishInstall(aInstall, aReason);
}
void Root::cancelDownload(InstallRef aInstall)
void Root::failedInstall(InstallRef aInstall, Delegate::FailureCode aReason)
{
RootPrivate::UpdateDeque::iterator it =
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
SG_LOG(SG_GENERAL, SG_ALERT, "failed to install package:"
<< aInstall->package()->id() << ":" << aReason);
if (d->delegate) {
d->delegate->failedInstall(aInstall.ptr(), aReason);
}
startNext(aInstall);
}
void Root::catalogRefreshStatus(CatalogRef aCat, Delegate::StatusCode aReason)
void Root::catalogRefreshBegin(CatalogRef aCat)
{
d->refreshing.insert(aCat);
}
void Root::catalogRefreshComplete(CatalogRef aCat, Delegate::FailureCode aReason)
{
CatalogDict::iterator catIt = d->catalogs.find(aCat->id());
d->fireRefreshStatus(aCat, aReason);
if (aReason != Delegate::FAIL_SUCCESS) {
if (d->delegate) {
d->delegate->failedRefresh(aCat, aReason);
}
if (aReason == Delegate::STATUS_IN_PROGRESS) {
d->refreshing.insert(aCat);
} else {
d->refreshing.erase(aCat);
}
if ((aReason != Delegate::STATUS_REFRESHED) && (aReason != Delegate::STATUS_IN_PROGRESS)) {
// if the failure is permanent, delete the catalog from our
// list (don't touch it on disk)
bool isPermanentFailure = (aReason == Delegate::FAIL_VERSION);
@@ -496,97 +323,17 @@ void Root::catalogRefreshStatus(CatalogRef aCat, Delegate::StatusCode aReason)
d->catalogs.erase(catIt);
}
}
}
if ((aReason == Delegate::STATUS_REFRESHED) && (catIt == d->catalogs.end())) {
assert(!aCat->id().empty());
} 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()) {
d->fireRefreshStatus(CatalogRef(), Delegate::STATUS_REFRESHED);
d->firePackagesChanged();
}
}
bool Root::removeCatalogById(const std::string& aId)
{
CatalogDict::iterator catIt = d->catalogs.find(aId);
if (catIt == d->catalogs.end()) {
SG_LOG(SG_GENERAL, SG_WARN, "removeCatalogById: unknown ID:" << aId);
return false;
}
CatalogRef 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());
if (d->delegate) {
d->delegate->refreshComplete();
}
// 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
+7 -38
View File
@@ -62,9 +62,7 @@ public:
void setLocale(const std::string& aLocale);
void addDelegate(Delegate* aDelegate);
void removeDelegate(Delegate* aDelegate);
void setDelegate(Delegate* aDelegate);
std::string getLocale() const;
@@ -83,16 +81,10 @@ public:
void makeHTTPRequest(HTTP::Request* req);
/**
* The catalog XML/property version in use. This is used to make incomaptible
* changes to the package/catalog syntax
*/
int catalogVersion() const;
/**
* the version string of the application. Catalogs must match this version,
* the version string of the root. Catalogs must match this version,
* 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)
@@ -100,11 +92,6 @@ public:
*/
void refresh(bool aForce = false);
/**
*
*/
PackageList allPackages() const;
/**
* retrieve packages matching a filter.
* filter consists of required / minimum values, AND-ed together.
@@ -122,39 +109,21 @@ public:
CatalogRef getCatalogById(const std::string& aId) const;
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:
friend class Install;
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 startInstall(InstallRef aInstall);
void installProgress(InstallRef aInstall, unsigned int aBytes, unsigned int aTotal);
void finishInstall(InstallRef aInstall, Delegate::StatusCode aReason);
void cancelDownload(InstallRef aInstall);
void finishInstall(InstallRef aInstall);
void failedInstall(InstallRef aInstall, Delegate::FailureCode aReason);
void registerInstall(InstallRef ins);
void unregisterInstall(InstallRef ins);
class ThumbnailDownloader;
class RootPrivate;
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];
#if ((defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__) || \
defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM) )
#ifndef WORDS_BIGENDIAN
memcpy(in, block, sizeof(in));
#else
for (a = 0; a < MD5_BLOCK_LENGTH / 4; a++) {
+16 -22
View File
@@ -34,28 +34,22 @@ bool keepRunning = true;
class MyDelegate : public pkg::Delegate
{
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;
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;
if (percent == _lastPercent) {
@@ -66,15 +60,15 @@ public:
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;
} else {
cerr << "failed install of " << aInstall->package()->name() << endl;
}
cout << "done install of " << aInstall->package()->name() << endl;
}
virtual void failedInstall(pkg::Install* aInstall, FailureCode aReason)
{
cerr << "failed install of " << aInstall->package()->name() << endl;
}
private:
unsigned int _lastPercent;
@@ -125,10 +119,10 @@ int main(int argc, char** argv)
pkg::Root* root = new pkg::Root(Dir::current().path(), "");
MyDelegate dlg;
root->addDelegate(&dlg);
root->setDelegate(&dlg);
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);
+4 -4
View File
@@ -144,9 +144,9 @@ public:
#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
@@ -237,9 +237,9 @@ public:
return (s == value);
}
SGPropertyNode* node(bool aCreate = false) const
SGPropertyNode* node() const
{
return PropertyObjectBase::node(aCreate);
return PropertyObjectBase::node(false);
}
private:
};
+33 -254
View File
@@ -11,6 +11,8 @@
#endif
#include "props.hxx"
#include "PropertyInterpolationMgr.hxx"
#include "vectorPropTemplates.hxx"
#include <algorithm>
#include <limits>
@@ -22,30 +24,31 @@
#include <stdio.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
# include <iostream>
using std::cerr;
#include <iostream>
#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 "vectorPropTemplates.hxx"
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
# if ( _MSC_VER == 1200 )
#if ( _MSC_VER == 1200 )
// MSVC 6 is buggy, and needs something strange here
using std::vector<SGPropertyNode_ptr>;
using std::vector<SGPropertyChangeListener *>;
using std::vector<SGPropertyNode *>;
# endif
#endif
#endif
#if PROPS_STANDALONE
using std::cerr;
#endif
using std::endl;
using std::find;
using std::sort;
@@ -81,14 +84,6 @@ public:
// Local path normalization code.
////////////////////////////////////////////////////////////////////////
#if PROPS_STANDALONE
struct PathComponent
{
string name;
int index;
};
#endif
/**
* Parse the name for a path component.
*
@@ -151,149 +146,10 @@ inline bool validateName(const std::string& name)
return false;
if (!isalpha(name[0]) && name[0] != '_')
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()),
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.
////////////////////////////////////////////////////////////////////////
@@ -326,13 +182,6 @@ static int
find_child (Itr begin, Itr end, int index, const PropertyList& nodes)
{
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);
for (size_t i = 0; i < nNodes; 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))
return static_cast<int>(i);
}
#endif
return -1;
}
@@ -485,57 +333,11 @@ find_node_aux(SGPropertyNode * current, SplitItr& itr, bool create,
// Internal function for parsing property paths. last_index provides
// 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>
SGPropertyNode*
find_node (SGPropertyNode * current,
const Range& path,
bool create,
bool create,
int last_index = -1)
{
using namespace boost;
@@ -549,7 +351,6 @@ find_node (SGPropertyNode * current,
else
return find_node_aux(current, itr, create, last_index);
}
#endif
////////////////////////////////////////////////////////////////////////
// Private methods from SGPropertyNode (may be inlined for speed).
@@ -810,8 +611,13 @@ SGPropertyNode::make_string () const
void
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()
<< ", value \"" << make_string() << '"');
#endif
}
/**
@@ -820,8 +626,13 @@ SGPropertyNode::trace_write () const
void
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()
<< ", value \"" << make_string() << '"');
#endif
}
////////////////////////////////////////////////////////////////////////
@@ -975,6 +786,8 @@ SGPropertyNode::alias (SGPropertyNode * target)
return true;
}
#if PROPS_STANDALONE
#else
if (!target)
{
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() << ". "
"Source " << getPath() << " is a tied property.");
}
#endif
return false;
}
@@ -1143,18 +957,11 @@ SGPropertyNode::getChild (const char * name, int index, bool create)
SGPropertyNode *
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);
if (node) {
return node;
#endif
} else if (create) {
SGPropertyNode* node = new SGPropertyNode(name, index, this);
node = new SGPropertyNode(name, index, this);
_children.push_back(node);
fireChildAdded(node);
return node;
@@ -1828,14 +1635,12 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
case props::UNSPECIFIED:
result = set_string(value);
break;
#if !PROPS_STANDALONE
case props::VEC3D:
result = static_cast<SGRawValue<SGVec3d>*>(_value.val)->setValue(parseString<SGVec3d>(value));
break;
case props::VEC4D:
result = static_cast<SGRawValue<SGVec4d>*>(_value.val)->setValue(parseString<SGVec4d>(value));
break;
#endif
case props::NONE:
default:
break;
@@ -1847,7 +1652,6 @@ SGPropertyNode::setUnspecifiedValue (const char * value)
}
//------------------------------------------------------------------------------
#if !PROPS_STANDALONE
bool SGPropertyNode::interpolate( const std::string& type,
const SGPropertyNode& target,
double duration,
@@ -1897,7 +1701,6 @@ simgear::PropertyInterpolationMgr* SGPropertyNode::getInterpolationMgr()
}
simgear::PropertyInterpolationMgr* SGPropertyNode::_interpolation_mgr = 0;
#endif
//------------------------------------------------------------------------------
std::ostream& SGPropertyNode::printOn(std::ostream& stream) const
@@ -2051,37 +1854,20 @@ SGPropertyNode::getRootNode () const
SGPropertyNode *
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;
return find_node(this, make_iterator_range(relative_path, relative_path
+ strlen(relative_path)),
create);
#endif
}
SGPropertyNode *
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;
return find_node(this, make_iterator_range(relative_path, relative_path
+ strlen(relative_path)),
create, index);
#endif
}
const SGPropertyNode *
@@ -2529,7 +2315,6 @@ SGPropertyChangeListener::unregister_property (SGPropertyNode * node)
_properties.erase(it);
}
#if !PROPS_STANDALONE
template<>
std::ostream& SGRawBase<SGVec3d>::printOn(std::ostream& stream) const
{
@@ -2566,11 +2351,9 @@ std::ostream& SGRawBase<SGVec4d>::printOn(std::ostream& stream) const
}
return stream;
}
#endif
namespace simgear
{
#if !PROPS_STANDALONE
template<>
std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result)
{
@@ -2579,7 +2362,6 @@ std::istream& readFrom<SGVec4d>(std::istream& stream, SGVec4d& result)
}
return stream;
}
#endif
namespace
{
@@ -2607,12 +2389,10 @@ bool compareNodeValue(const SGPropertyNode& lhs, const SGPropertyNode& rhs)
case props::STRING:
case props::UNSPECIFIED:
return !strcmp(lhs.getStringValue(), rhs.getStringValue());
#if !PROPS_STANDALONE
case props::VEC3D:
return lhs.getValue<SGVec3d>() == rhs.getValue<SGVec3d>();
case props::VEC4D:
return lhs.getValue<SGVec4d>() == rhs.getValue<SGVec4d>();
#endif
default:
return false;
}
@@ -2669,10 +2449,10 @@ struct PropertyPlaceLess {
}
};
#if !PROPS_STANDALONE
size_t hash_value(const SGPropertyNode& node)
{
using namespace boost;
if (node.nChildren() == 0) {
switch (node.getType()) {
case props::NONE:
@@ -2723,6 +2503,5 @@ size_t hash_value(const SGPropertyNode& node)
return seed;
}
}
#endif
// end of props.cxx
+9 -49
View File
@@ -22,54 +22,24 @@
#include <sstream>
#include <typeinfo>
#include <simgear/compiler.h>
#include <boost/utility.hpp>
#include <boost/type_traits/is_enum.hpp>
#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
# include <boost/utility.hpp>
# include <boost/type_traits/is_enum.hpp>
# include <simgear/debug/logstream.hxx>
# include <simgear/math/SGMathFwd.hxx>
# include <simgear/math/sg_types.hxx>
#include <simgear/compiler.h>
#include <simgear/debug/logstream.hxx>
#endif
#include <simgear/math/SGMathFwd.hxx>
#include <simgear/math/sg_types.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
// XXX This whole file should be in the simgear namespace, but I don't
// have the guts yet...
using namespace std;
namespace simgear
{
@@ -1305,7 +1275,6 @@ public:
return ret;
}
#if !PROPS_STANDALONE
/**
* Interpolate current value to target value within given time.
*
@@ -1341,7 +1310,6 @@ public:
* Get the interpolation manager
*/
static simgear::PropertyInterpolationMgr* getInterpolationMgr();
#endif
/**
* Print the value of the property to a stream.
@@ -1839,11 +1807,7 @@ private:
// Convenience functions for use in templates
template<typename T>
#if PROPS_STANDALONE
T
#else
typename boost::disable_if<boost::is_enum<T>, T>::type
#endif
getValue(const SGPropertyNode*);
template<>
@@ -1907,11 +1871,7 @@ namespace simgear
/** Extract enum from SGPropertyNode */
template<typename T>
#if PROPS_STANDALONE
inline T
#else
inline typename boost::enable_if<boost::is_enum<T>, T>::type
#endif
getValue(const SGPropertyNode* node)
{
typedef simgear::enum_traits<T> Traits;
-10
View File
@@ -326,15 +326,9 @@ public:
= GL2Extensions::Get(static_cast<unsigned>(contextId), true);
if (!extensions)
return;
#if OSG_VERSION_LESS_THAN(3,3,4)
if (!extensions->isGlslSupported())
return;
value = extensions->getLanguageVersion();
#else
if (!extensions->isGlslSupported)
return;
value = extensions->glslLanguageVersion;
#endif
}
};
@@ -363,11 +357,7 @@ public:
= GL2Extensions::Get(static_cast<unsigned>(contextId), true);
if (!extensions)
return;
#if OSG_VERSION_LESS_THAN(3,3,4)
value = extensions->isGlslSupported();
#else
value = extensions->isGlslSupported;
#endif
}
};
-1
View File
@@ -323,7 +323,6 @@ SGMaterial::read_properties(const SGReaderWriterOptions* options,
// Random vegetation properties
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_width = props->getDoubleValue("tree-width-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; }
/**
* 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
* 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
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
// random vegetation, objects and buildings
std::vector<Texture2DRef> _masks;
+2 -2
View File
@@ -201,7 +201,7 @@ SGMaterialCache *SGMaterialLib::generateMatCache(SGGeod center)
// Destructor
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)
@@ -244,5 +244,5 @@ SGMaterial *SGMaterialCache::find(const string& material) const
// Destructor
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) {
std::string textureName = _textureProp->getStringValue();
if (_textureName != textureName) {
_textureName = textureName;
while (stateSet->getTextureAttribute(0,
osg::StateAttribute::TEXTURE)) {
stateSet->removeTextureAttribute(0, osg::StateAttribute::TEXTURE);
@@ -379,12 +377,8 @@ public:
osg::StateAttribute::OVERRIDE);
stateSet->setTextureMode(0, GL_TEXTURE_2D,
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)
{
osgDB::Registry::instance()->getDataFilePathList().push_front(root_dir);
osgDB::Registry::instance()->getOptions()->getDatabasePathList().push_front(root_dir);
static_propRoot = root;
}
@@ -115,7 +114,6 @@ SGModelLib::loadModel(const string &path,
{
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
opt->getDatabasePathList().push_front( osgDB::getFilePath(path) );
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
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->setFileName(0, path);
osg::ref_ptr<SGReaderWriterOptions> opt;
opt = SGReaderWriterOptions::copyOrCreate(osgDB::Registry::instance()->getOptions());
opt->getDatabasePathList().push_front( osgDB::getFilePath(path) );
opt->setPropertyNode(prop_root ? prop_root: static_propRoot.get());
opt->setModelData(data);
opt->setLoadPanel(static_panelFunc);
@@ -128,11 +128,7 @@ void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
sortData.frameSorted = frameNumber;
}
#if OSG_VERSION_LESS_THAN(3,3,4)
const Extensions* extensions = getExtensions(state.getContextID(),true);
#else
const GLExtensions* extensions = GLExtensions::Get(state.getContextID(), true);
#endif
GLfloat ua1[3] = { (GLfloat) alpha_factor,
(GLfloat) shade_factor,
(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 );
// 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
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
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:
// * 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] < 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( o_halo_color._v );
gamma_correct_rgb( scene_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)
{
sun_color[3] = 0;
o_halo_color[3]=0;
i_halo_color[3]=0;
brilliance_color[3]=0;
}
(*sun_cl)[0] = sun_color;
@@ -409,8 +356,6 @@ bool SGSun::repaint( double sun_angle, double new_visibility ) {
ihalo_cl->dirty();
(*ohalo_cl)[0] = o_halo_color;
ohalo_cl->dirty();
(*brilliance_cl)[0] = brilliance_color;
brilliance_cl->dirty();
}
return true;
@@ -427,14 +372,19 @@ bool SGSun::reposition( double rightAscension, double declination,
{
// GST - GMT sidereal time
osg::Matrix T2, RA, DEC;
// xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0),
// 0.0, 0.0, 1.0);
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);
DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
// xglTranslatef(0,sun_dist);
T2.makeTranslate(osg::Vec3(0, sun_dist, 0));
sun_transform->setMatrix(T2*DEC*RA);
// Suncolor related things:
if ( prev_sun_angle != sun_angle ) {
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;
//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
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> ihalo_cl;
osg::ref_ptr<osg::Vec4Array> ohalo_cl;
osg::ref_ptr<osg::Vec4Array> brilliance_cl;
double visibility;
double prev_sun_angle;
+35 -67
View File
@@ -44,7 +44,6 @@
#include <simgear/misc/sgstream.hxx>
#include <simgear/scene/util/OptionsReadFileCallback.hxx>
#include <simgear/scene/util/OsgMath.hxx>
#include <simgear/scene/util/QuadTreeBuilder.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/scene/tgdb/apt_signs.hxx>
@@ -114,79 +113,48 @@ struct ReaderWriterSTG::_ModelBin {
};
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:
virtual osgDB::ReaderWriter::ReadResult
readNode(const std::string&, const osgDB::Options*)
{
STGObjectsQuadtree quadtree((GetModelLODCoord()), (AddModelLOD()));
quadtree.buildQuadTree(_objectStaticList.begin(), _objectStaticList.end());
osg::ref_ptr<osg::Group> group = quadtree.getRoot();
osg::ref_ptr<osg::Group> group = new osg::Group;
group->setName("STG-group-A");
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());
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);
+5 -5
View File
@@ -386,10 +386,10 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
int row = ((int) (mt_rand(&seed) * 1000)) % 5;
float base_y = (float) row * 16.0 * 3.0 / 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 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
for (unsigned int i = 0; i < 16; i++) {
@@ -424,7 +424,7 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
if (building.pitched) {
// Use the entire height of the roof texture
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;
front_x = 480.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;
float base_y = 288 / 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;
// BASEMENT - uses the baseline texture
@@ -560,7 +560,7 @@ BuildingBoundingBoxCallback::computeBound(const Drawable& drawable) const
int column = ((int) (mt_rand(&seed) * 1000)) % 8;
float base_y = 576 / 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;
// BASEMENT - uses the baseline texture
+1 -4
View File
@@ -291,8 +291,7 @@ public:
float vegetation_density,
float cos_max_density_angle,
float cos_zero_density_angle,
std::vector<SGVec3f>& points,
std::vector<SGVec3f>& normals)
std::vector<SGVec3f>& points)
{
if ( !geometries.empty() ) {
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()) {
// The red channel contains the rotation for this object
points.push_back(randomPoint);
normals.push_back(normalize(normal));
}
} else {
points.push_back(randomPoint);
normals.push_back(normalize(normal));
}
}
}
+5 -9
View File
@@ -28,7 +28,6 @@
#include <osg/Geometry>
#include <osg/PrimitiveSet>
#include <osg/Texture2D>
#include <osg/ref_ptr>
#include <stdio.h>
#include <simgear/math/sg_random.h>
@@ -123,16 +122,16 @@ public:
osg::DrawElements* getDrawElements()
{
if (count > 65535) {
_ushortElements = 0;
free (_ushortElements);
return _uintElements;
} else {
_uintElements = 0;
free (_uintElements);
return _ushortElements;
}
}
protected:
osg::ref_ptr<osg::DrawElementsUShort> _ushortElements;
osg::ref_ptr<osg::DrawElementsUInt> _uintElements;
osg::DrawElementsUShort* _ushortElements;
osg::DrawElementsUInt* _uintElements;
unsigned count;
};
@@ -216,8 +215,7 @@ public:
float vegetation_density,
float cos_max_density_angle,
float cos_zero_density_angle,
std::vector<SGVec3f>& points,
std::vector<SGVec3f>& normals)
std::vector<SGVec3f>& points)
{
unsigned num = getNumTriangles();
for (unsigned i = 0; i < num; ++i) {
@@ -283,11 +281,9 @@ public:
if (mt_rand(&seed) < img->getColor(x, y).g()) {
// The red channel contains the rotation for this object
points.push_back(randomPoint);
normals.push_back(normalize(normal));
}
} else {
points.push_back(randomPoint);
normals.push_back(normalize(normal));
}
}
}
+11 -12
View File
@@ -97,7 +97,7 @@ public:
virtual ~SGTileDetailsCallback()
{
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(
@@ -723,7 +723,6 @@ public:
BOOST_FOREACH(bin, randomForest)
{
if ((bin->texture == mat->get_tree_texture() ) &&
(bin->teffect == mat->get_tree_effect() ) &&
(bin->texture_varieties == mat->get_tree_varieties()) &&
(bin->range == mat->get_tree_range() ) &&
(bin->width == mat->get_tree_width() ) &&
@@ -736,9 +735,7 @@ public:
if (!found) {
bin = new TreeBin();
bin->texture = mat->get_tree_texture();
SG_LOG(SG_TERRAIN, SG_DEBUG, "Tree texture " << bin->texture);
bin->teffect = mat->get_tree_effect();
SG_LOG(SG_TERRAIN, SG_DEBUG, "Tree effect " << bin->teffect);
SG_LOG(SG_INPUT, SG_DEBUG, "Tree texture " << bin->texture);
bin->range = mat->get_tree_range();
bin->width = mat->get_tree_width();
bin->height = mat->get_tree_height();
@@ -747,19 +744,16 @@ public:
}
std::vector<SGVec3f> randomPoints;
std::vector<SGVec3f> randomPointNormals;
matTris[i].addRandomTreePoints(wood_coverage,
mat->get_one_object_mask(matTris[i].getTextureIndex()),
vegetation_density,
mat->get_cos_tree_max_density_slope_angle(),
mat->get_cos_tree_zero_density_slope_angle(),
randomPoints,
randomPointNormals);
randomPoints);
std::vector<SGVec3f>::iterator k;
std::vector<SGVec3f>::iterator j;
for (k = randomPoints.begin(), j = randomPointNormals.begin(); k != randomPoints.end(); ++k, ++j) {
bin->insert(*k, *j);
for (k = randomPoints.begin(); k != randomPoints.end(); ++k) {
bin->insert(*k);
}
}
}
@@ -789,6 +783,11 @@ public:
float coverage = mat->get_light_coverage();
if (coverage <= 0)
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();
@@ -872,7 +871,7 @@ public:
lightGroup->addChild(groundLights2);
}
if (! vasiLights.empty()) {
if (vasiLights.empty()) {
EffectGeode* vasiGeode = new EffectGeode;
Effect* vasiEffect = getLightEffect(24, osg::Vec3(1, 0.0001, 0.000001), 1, 24, true, _options);
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
{
State& state = *renderInfo.getState();
#if OSG_VERSION_LESS_THAN(3,3,4)
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 cend = _posScaleArray->end();
FloatArray::const_iterator viter = _vertexAttribArray->begin();
+7 -45
View File
@@ -49,7 +49,6 @@
#include <simgear/scene/util/QuadTreeBuilder.hxx>
#include <simgear/scene/util/RenderConstants.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
#include <simgear/structure/OSGUtils.hxx>
#include "ShaderGeometry.hxx"
@@ -63,9 +62,6 @@ using namespace osg;
namespace simgear
{
bool use_tree_shadows;
bool use_tree_normals;
// Tree instance scheme:
// vertex - local position of quad vertex.
// normal - x y scaling, z number of varieties
@@ -168,24 +164,15 @@ Geometry* createTreeGeometry(float width, float height, int varieties)
// Positions
quadGeom->setColorArray(new Vec3Array);
quadGeom->setColorBinding(Geometry::BIND_PER_VERTEX);
// Normals
if (use_tree_shadows || use_tree_normals)
{
quadGeom->setSecondaryColorArray(new Vec3Array);
quadGeom->setSecondaryColorBinding(Geometry::BIND_PER_VERTEX);
}
FloatArray* rotation = new FloatArray(3);
FloatArray* rotation = new FloatArray(2);
(*rotation)[0] = 0.0;
(*rotation)[1] = PI_2;
if (use_tree_shadows) {(*rotation)[2] = -1.0;}
quadGeom->setFogCoordArray(rotation);
quadGeom->setFogCoordBinding(Geometry::BIND_PER_PRIMITIVE_SET);
// The primitive sets render the same geometry, but the second
// will rotated 90 degrees by the vertex shader, which uses the
// fog coordinate as a rotation.
int imax = 2;
if (use_tree_shadows) {imax = 3;}
for (int i = 0; i < imax; ++i)
for (int i = 0; i < 2; ++i)
quadGeom->addPrimitiveSet(new DrawArrays(PrimitiveSet::QUADS));
return quadGeom;
}
@@ -197,17 +184,13 @@ EffectGeode* createTreeGeode(float width, float height, int varieties)
return result;
}
void addTreeToLeafGeode(Geode* geode, const SGVec3f& p, const SGVec3f& t)
void addTreeToLeafGeode(Geode* geode, const SGVec3f& p)
{
Vec3 pos = toOsg(p);
Vec3 ter = toOsg(t);
unsigned int numDrawables = geode->getNumDrawables();
Geometry* geom
= static_cast<Geometry*>(geode->getDrawable(numDrawables - 1));
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()
>= static_cast<Vec3Array*>(geom->getVertexArray())->size()) {
Vec3Array* paramsArray
@@ -215,17 +198,11 @@ void addTreeToLeafGeode(Geode* geode, const SGVec3f& p, const SGVec3f& t)
Vec3 params = (*paramsArray)[0];
geom = createTreeGeometry(params.x(), params.y(), params.z());
posArray = static_cast<Vec3Array*>(geom->getColorArray());
if (use_tree_shadows || use_tree_normals)
{tnormalArray = static_cast<Vec3Array*>(geom->getSecondaryColorArray());}
geode->addDrawable(geom);
}
posArray->insert(posArray->end(), 4, pos);
if (use_tree_shadows || use_tree_normals)
{tnormalArray->insert(tnormalArray->end(),4,ter);}
size_t numVerts = posArray->size();
int imax = 2;
if (use_tree_shadows) {imax = 3;}
for (int i = 0; i < imax; ++i) {
for (int i = 0; i < 2; ++i) {
DrawArrays* primSet
= static_cast<DrawArrays*>(geom->getPrimitiveSet(i));
primSet->setCount(numVerts);
@@ -278,7 +255,7 @@ struct AddTreesLeafObject
void operator() (LOD* lod, const TreeBin::Tree& tree) const
{
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
{
Vec3 pos = toOsg(tree.position);
Vec3 norm = toOsg(tree.tnormal);
return TreeBin::Tree(toSG(pos * mat),toSG(norm * mat));
return TreeBin::Tree(toSG(pos * mat));
}
Matrix mat;
};
@@ -357,20 +333,6 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
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) {
TreeBin* forest = *i;
@@ -381,7 +343,7 @@ osg::Group* createForest(SGTreeBinList& forestList, const osg::Matrix& transform
(!iter->second.lock(effect)))
{
SGPropertyNode_ptr effectProp = new SGPropertyNode;
makeChild(effectProp, "inherits-from")->setStringValue(forest->teffect);
makeChild(effectProp, "inherits-from")->setStringValue("Effects/tree");
SGPropertyNode* params = makeChild(effectProp, "parameters");
// emphasize n = 0
params->getChild("texture", 0, true)->getChild("image", 0, true)
+5 -7
View File
@@ -36,10 +36,10 @@ namespace simgear
class TreeBin {
public:
struct Tree {
SGVec3f position;
SGVec3f tnormal;
Tree(const SGVec3f& p, const SGVec3f& t) : position(p),tnormal(t)
Tree(const SGVec3f& p) :
position(p)
{ }
SGVec3f position;
};
typedef std::vector<Tree> TreeList;
@@ -49,13 +49,11 @@ public:
float height;
float width;
std::string texture;
std::string teffect;
void insert(const Tree& t)
{ _trees.push_back(t); }
void insert(const SGVec3f& p, const SGVec3f& tnorm)
{insert(Tree(p,tnorm));}
void insert(const SGVec3f& p, int t, float s)
{ insert(Tree(p)); }
unsigned getNumTrees() const
{ return _trees.size(); }
+31 -90
View File
@@ -51,7 +51,6 @@
#include <map>
#include <simgear/compiler.h>
#include <simgear/version.h>
#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 /////////////////////////////////////////////////////
@@ -344,7 +306,7 @@ SGTerraSync::SvnThread::SvnThread() :
_stop(false),
_use_svn(true)
{
_http.setUserAgent("terrascenery-" SG_STRINGIZE(SIMGEAR_VERSION));
_http.setUserAgent("terrascenery-" SG_STRINGIZE(SG_VERSION));
}
void SGTerraSync::SvnThread::stop()
@@ -370,7 +332,7 @@ bool SGTerraSync::SvnThread::start()
if (_local_dir=="")
{
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Local cache directory is undefined.");
_fail_count++;
_stalled = true;
@@ -380,7 +342,7 @@ bool SGTerraSync::SvnThread::start()
SGPath path(_local_dir);
if (!path.exists())
{
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Directory '" << _local_dir <<
"' does not exist. Set correct directory path or create directory folder.");
_fail_count++;
@@ -391,7 +353,7 @@ bool SGTerraSync::SvnThread::start()
path.append("version");
if (path.exists())
{
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Directory '" << _local_dir <<
"' contains the base package. Use a separate directory.");
_fail_count++;
@@ -401,10 +363,17 @@ bool SGTerraSync::SvnThread::start()
_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==""))
{
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot start scenery download. Rsync scenery server is undefined.");
_fail_count++;
_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
// 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. "
<< status
<< "Directory: '" << _local_dir << "'.");
@@ -476,7 +445,7 @@ bool SGTerraSync::SvnThread::runExternalSyncCommand(const char* dir)
#else
command = buf.str();
#endif
SG_LOG(SG_TERRASYNC,SG_DEBUG, "sync command '" << command << "'");
SG_LOG(SG_TERRAIN,SG_DEBUG, "sync command '" << command << "'");
#ifdef SG_WINDOWS
// tbd: does Windows support "popen"?
@@ -491,7 +460,7 @@ bool SGTerraSync::SvnThread::runExternalSyncCommand(const char* dir)
if (rc)
{
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Failed to synchronize directory '" << dir << "', " <<
"error code= " << rc);
return false;
@@ -504,32 +473,6 @@ void SGTerraSync::SvnThread::run()
_active = true;
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) {
runInternal();
} else {
@@ -552,7 +495,7 @@ void SGTerraSync::SvnThread::runExternal()
SyncItem::Status cacheStatus = isPathCached(next);
if (cacheStatus != SyncItem::Invalid) {
_cache_hits++;
SG_LOG(SG_TERRASYNC, SG_DEBUG,
SG_LOG(SG_TERRAIN, SG_DEBUG,
"Cache hit for: '" << next._dir << "'");
next._status = cacheStatus;
_freshTiles.push_back(next);
@@ -582,7 +525,7 @@ void SGTerraSync::SvnThread::syncPathExternal(const SyncItem& next)
if (isNewDirectory) {
int rc = path.create_dir( 0755 );
if (rc) {
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot create directory '" << path << "', return code = " << rc );
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->isDoingSync()) {
#if 1
if (slot.stamp.elapsedMSec() > (int)slot.nextWarnTimeout) {
SG_LOG(SG_TERRASYNC, 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());
#if 0
if (slot.stamp.elapsedMSec() > slot.nextWarnTimeout) {
SG_LOG(SG_TERRAIN, SG_INFO, "sync taking a long time:" << slot.currentItem._dir << " taken " << slot.stamp.elapsedMSec());
SG_LOG(SG_TERRAIN, SG_INFO, "HTTP status:" << _http.hasActiveRequests());
slot.nextWarnTimeout += 10000;
}
#endif
@@ -623,7 +566,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
fail(slot.currentItem);
} else {
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");
}
@@ -643,7 +586,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
if (slot.isNewDirectory) {
int rc = path.create_dir( 0755 );
if (rc) {
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Cannot create directory '" << path << "', return code = " << rc );
fail(slot.currentItem);
return;
@@ -662,7 +605,7 @@ void SGTerraSync::SvnThread::updateSyncSlot(SyncSlot &slot)
slot.nextWarnTimeout = 20000;
slot.stamp.stamp();
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);
if (cacheStatus != SyncItem::Invalid) {
_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;
_freshTiles.push_back(next);
_is_dirty = true;
@@ -740,8 +683,6 @@ void SGTerraSync::SvnThread::fail(SyncItem failedItem)
_fail_count++;
failedItem._status = SyncItem::Failed;
_freshTiles.push_back(failedItem);
SG_LOG(SG_TERRASYNC,SG_INFO,
"Failed to sync'" << failedItem._dir << "'");
_completedTiles[ failedItem._dir ] = now + UpdateInterval::FailedAttempt;
_is_dirty = true;
}
@@ -766,7 +707,7 @@ void SGTerraSync::SvnThread::updated(SyncItem item, bool isNewDirectory)
time_t now = time(0);
_consecutive_errors = 0;
_success_count++;
SG_LOG(SG_TERRASYNC,SG_INFO,
SG_LOG(SG_TERRAIN,SG_INFO,
"Successfully synchronized directory '" << item._dir << "'");
item._status = SyncItem::Updated;
@@ -792,7 +733,7 @@ void SGTerraSync::SvnThread::initCompletedTilesPersistentCache()
try {
readProperties(_persistentCachePath.str(), cacheRoot);
} 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;
}
@@ -853,7 +794,7 @@ SGTerraSync::SGTerraSync() :
_inited(false)
{
_svnThread = new SvnThread();
_log = new BufferedLogCallback(SG_TERRASYNC, SG_INFO);
_log = new BufferedLogCallback(SG_TERRAIN, SG_INFO);
_log->truncateAt(255);
sglog().addCallback(_log);
@@ -978,13 +919,13 @@ void SGTerraSync::update(double)
{
if (_svnThread->_stalled)
{
SG_LOG(SG_TERRASYNC,SG_ALERT,
SG_LOG(SG_TERRAIN,SG_ALERT,
"Automatic scenery download/synchronization stalled. Too many errors.");
}
else
{
// 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.");
}
_stalledNode->setBoolValue(_svnThread->_stalled);
-22
View File
@@ -25,13 +25,11 @@
#include "SGSceneFeatures.hxx"
#include <osg/Version>
#include <osg/FragmentProgram>
#include <osg/VertexProgram>
#include <osg/Point>
#include <osg/PointSprite>
#include <osg/Texture>
#include <osg/GLExtensions>
#include <OpenThreads/Mutex>
#include <OpenThreads/ScopedLock>
@@ -86,18 +84,12 @@ SGSceneFeatures::setTextureCompression(osg::Texture* texture) const
bool
SGSceneFeatures::getHavePointSprites(unsigned contextId) const
{
#if OSG_VERSION_LESS_THAN(3,3,4)
return osg::PointSprite::isPointSpriteSupported(contextId);
#else
const osg::GLExtensions* ex = osg::GLExtensions::Get(contextId, true);
return ex && ex->isPointSpriteSupported;
#endif
}
bool
SGSceneFeatures::getHaveFragmentPrograms(unsigned contextId) const
{
#if OSG_VERSION_LESS_THAN(3,3,4)
const osg::FragmentProgram::Extensions* fpe;
fpe = osg::FragmentProgram::getExtensions(contextId, true);
if (!fpe)
@@ -106,16 +98,11 @@ SGSceneFeatures::getHaveFragmentPrograms(unsigned contextId) const
return false;
return true;
#else
const osg::GLExtensions* ex = osg::GLExtensions::Get(contextId, true);
return ex && ex->isFragmentProgramSupported;
#endif
}
bool
SGSceneFeatures::getHaveVertexPrograms(unsigned contextId) const
{
#if OSG_VERSION_LESS_THAN(3,3,4)
const osg::VertexProgram::Extensions* vpe;
vpe = osg::VertexProgram::getExtensions(contextId, true);
if (!vpe)
@@ -124,10 +111,6 @@ SGSceneFeatures::getHaveVertexPrograms(unsigned contextId) const
return false;
return true;
#else
const osg::GLExtensions* ex = osg::GLExtensions::Get(contextId, true);
return ex && ex->isVertexProgramSupported;
#endif
}
bool
@@ -141,7 +124,6 @@ SGSceneFeatures::getHaveShaderPrograms(unsigned contextId) const
bool
SGSceneFeatures::getHavePointParameters(unsigned contextId) const
{
#if OSG_VERSION_LESS_THAN(3,3,4)
const osg::Point::Extensions* pe;
pe = osg::Point::getExtensions(contextId, true);
if (!pe)
@@ -149,9 +131,5 @@ SGSceneFeatures::getHavePointParameters(unsigned contextId) const
if (!pe->isPointParametersSupported())
return false;
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 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
void SGSampleGroup::update_pos_and_orientation() {
SGVec3d base_position = SGVec3d::fromGeod(_base_pos);
SGVec3d smgr_position = _smgr->get_position();
SGVec3d position = SGVec3d::fromGeod(_base_pos) - _smgr->get_position();
SGQuatd hlOr = SGQuatd::fromLonLat(_base_pos);
SGQuatd ec2body = hlOr*_orientation;
@@ -419,14 +418,12 @@ void SGSampleGroup::update_pos_and_orientation() {
sample->set_master_volume( _volume );
sample->set_orientation( _orientation );
sample->set_rotation( ec2body );
sample->set_position(base_position);
sample->set_position( position );
sample->set_velocity( velocity );
// Test if a sample is farther away than max distance, if so
// stop the sound playback and free it's source.
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 dist2 = position[0]*position[0]
+ position[1]*position[1] + position[2]*position[2];
@@ -452,7 +449,7 @@ void SGSampleGroup::update_sample_config( SGSoundSample *sample )
} else {
sample->update_pos_and_orientation();
orientation = sample->get_orientation();
position = sample->get_position() - _smgr->get_position();
position = sample->get_position();
velocity = sample->get_velocity();
}
+7 -31
View File
@@ -28,7 +28,6 @@
#include <stdlib.h> // rand(), free()
#include <cstring>
#include <stdio.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/structure/exception.hxx>
@@ -79,12 +78,8 @@ SGSoundSample::SGSoundSample() :
_playing(false),
_static_changed(true),
_out_of_range(false),
_is_file(false),
_use_pos_props(false)
_is_file(false)
{
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
}
// constructor
@@ -119,14 +114,10 @@ SGSoundSample::SGSoundSample(const char *file, const SGPath& currentDir) :
_playing(false),
_static_changed(true),
_out_of_range(false),
_is_file(true),
_use_pos_props(false)
_is_file(true)
{
SGPath p = simgear::ResourceManager::instance()->findPath(file, currentDir);
_refname = p.str();
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
}
// constructor
@@ -161,14 +152,10 @@ SGSoundSample::SGSoundSample( const unsigned char** data,
_playing(false),
_static_changed(true),
_out_of_range(false),
_is_file(false),
_use_pos_props(false)
_is_file(false)
{
SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" );
_data = (unsigned char*)*data; *data = NULL;
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
}
// constructor
@@ -202,14 +189,10 @@ SGSoundSample::SGSoundSample( void** data, int len, int freq, int format ) :
_playing(false),
_static_changed(true),
_out_of_range(false),
_is_file(false),
_use_pos_props(false)
_is_file(false)
{
SG_LOG( SG_SOUND, SG_DEBUG, "In memory sounds sample" );
_data = (unsigned char*)*data; *data = NULL;
_pos_prop[0] = 0;
_pos_prop[1] = 0;
_pos_prop[2] = 0;
}
@@ -220,16 +203,9 @@ SGSoundSample::~SGSoundSample() {
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;
if (_relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) {
_absolute_pos += _rotation.rotate( _relative_pos );
}
_absolute_pos = _base_pos;
if (_relative_pos[0] || _relative_pos[1] || _relative_pos[2] ) {
_absolute_pos += _rotation.rotate( _relative_pos );
}
_orivec = SGVec3f::zeros();

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