From 576979c562700aaacb34fdbc6d3d8ae6e74100dc Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 23 Oct 2011 11:26:19 +0100 Subject: [PATCH 01/25] Make lat/lon points in the ocean tile configurable at run-time. Not hooked up to a property yet, but soon. --- simgear/scene/tgdb/SGOceanTile.cxx | 49 +++++++++++++++++++----------- simgear/scene/tgdb/SGOceanTile.hxx | 2 +- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/simgear/scene/tgdb/SGOceanTile.cxx b/simgear/scene/tgdb/SGOceanTile.cxx index 2907bbac..def796cd 100644 --- a/simgear/scene/tgdb/SGOceanTile.cxx +++ b/simgear/scene/tgdb/SGOceanTile.cxx @@ -60,12 +60,11 @@ using namespace simgear; // it may be superfluous for such a small mesh. namespace { -const int lonPoints = 5; -const int latPoints = 5; - class OceanMesh { public: - OceanMesh(): + OceanMesh(int latP, int lonP): + latPoints(latP), + lonPoints(lonP), geoPoints(latPoints * lonPoints + 2 * (lonPoints + latPoints)), geod_nodes(latPoints * lonPoints), vl(new osg::Vec3Array(geoPoints)), @@ -75,11 +74,24 @@ public: nlArray(*nl, lonPoints + 2, lonPoints, 1), tlArray(*tl, lonPoints + 2, lonPoints, 1) { + int numPoints = latPoints * lonPoints; + geod = new SGGeod[numPoints]; + normals = new SGVec3f[numPoints]; + rel = new SGVec3d[numPoints]; } + + ~OceanMesh() + { + delete[] geod; + delete[] normals; + delete[] rel; + } + + const int latPoints, lonPoints; const int geoPoints; - SGGeod geod[latPoints][lonPoints]; - SGVec3f normals[latPoints][lonPoints]; - SGVec3d rel[latPoints][lonPoints]; + SGGeod* geod; + SGVec3f* normals; + SGVec3d* rel; std::vector geod_nodes; @@ -114,10 +126,11 @@ void OceanMesh::calcMesh(const SGVec3d& cartCenter, const SGQuatd& orient, for (int j = 0; j < latPoints; j++) { double lat = startLat + j * latInc; for (int i = 0; i < lonPoints; i++) { - geod[j][i] = SGGeod::fromDeg(startLon + i * longInc, lat); - SGVec3d cart = SGVec3d::fromGeod(geod[j][i]); - rel[j][i] = orient.transform(cart - cartCenter); - normals[j][i] = toVec3f(orient.transform(normalize(cart))); + int index = (j * lonPoints) + i; + geod[index] = SGGeod::fromDeg(startLon + i * longInc, lat); + SGVec3d cart = SGVec3d::fromGeod(geod[index]); + rel[index] = orient.transform(cart - cartCenter); + normals[index] = toVec3f(orient.transform(normalize(cart))); } } @@ -130,8 +143,9 @@ void OceanMesh::calcMesh(const SGVec3d& cartCenter, const SGQuatd& orient, VectorArrayAdapter rectArray(rectangle, lonPoints); for (int j = 0; j < latPoints; j++) { for (int i = 0; i < lonPoints; i++) { - geodNodesArray(j, i) = geod[j][i]; - rectArray(j, i) = j * 5 + i; + int index = (j * lonPoints) + i; + geodNodesArray(j, i) = geod[index]; + rectArray(j, i) = index; } } @@ -144,8 +158,9 @@ void OceanMesh::calcMesh(const SGVec3d& cartCenter, const SGQuatd& orient, for (int j = 0; j < latPoints; j++) { for (int i = 0; i < lonPoints; ++i) { - vlArray(j, i) = toOsg(rel[j][i]); - nlArray(j, i) = toOsg(normals[j][i]); + int index = (j * lonPoints) + i; + vlArray(j, i) = toOsg(rel[index]); + nlArray(j, i) = toOsg(normals[index]); tlArray(j, i) = toOsg(texsArray(j, i)); } } @@ -259,7 +274,7 @@ void fillDrawElementsWithApron(short height, short width, } } -osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib) +osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib, int latPoints, int lonPoints) { Effect *effect = 0; @@ -277,7 +292,7 @@ osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib) } else { SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean"); } - OceanMesh grid; + OceanMesh grid(latPoints, lonPoints); // Calculate center point SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center()); SGGeod geodPos = SGGeod::fromCart(cartCenter); diff --git a/simgear/scene/tgdb/SGOceanTile.hxx b/simgear/scene/tgdb/SGOceanTile.hxx index 3e48aebc..75b1f262 100644 --- a/simgear/scene/tgdb/SGOceanTile.hxx +++ b/simgear/scene/tgdb/SGOceanTile.hxx @@ -28,6 +28,6 @@ class SGBucket; class SGMaterialLib; // Generate an ocean tile -osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib); +osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib, int latPoints = 5, int lonPoints = 5); #endif // _SG_OBJ_HXX From a31639682b633e4b12b7153a975e9eb2d2ca7125 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 23 Oct 2011 15:59:27 +0100 Subject: [PATCH 02/25] Use a compile test to see if we need to provide the GCC atomic built-ins ourselves, or not. --- CMakeLists.txt | 9 ++++++++- simgear/simgear_config_cmake.h.in | 2 ++ simgear/structure/SGAtomic.cxx | 5 ++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f6729155..fc2d2630 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -99,7 +99,7 @@ find_package(ZLIB REQUIRED) find_package(Threads REQUIRED) if(SIMGEAR_HEADLESS) - message(STATUS "headlesss mode") + message(STATUS "headless mode") set(NO_OPENSCENEGRAPH_INTERFACE 1) else() find_package(OpenGL REQUIRED) @@ -179,6 +179,13 @@ check_cxx_source_compiles( if(CMAKE_COMPILER_IS_GNUCXX) set(WARNING_FLAGS -Wall) + + # certain GCC versions don't provide the atomic builds, and hence + # require is to provide them in SGAtomic.cxx + set(CMAKE_REQUIRED_INCLUDES ${CMAKE_INCLUDE_PATH}) + check_cxx_source_compiles( + "int main() { unsigned mValue; return __sync_add_and_fetch(&mValue, 1); }" + GCC_ATOMIC_BUILTINS_FOUND) endif(CMAKE_COMPILER_IS_GNUCXX) if(WIN32) diff --git a/simgear/simgear_config_cmake.h.in b/simgear/simgear_config_cmake.h.in index 3d132306..a1192283 100644 --- a/simgear/simgear_config_cmake.h.in +++ b/simgear/simgear_config_cmake.h.in @@ -16,5 +16,7 @@ #cmakedefine HAVE_SVN_CLIENT_H #cmakedefine HAVE_LIBSVN_CLIENT_1 +#cmakedefine GCC_ATOMIC_BUILTINS_FOUND + // set if building headless (no OSG or OpenGL libs) #cmakedefine NO_OPENSCENEGRAPH_INTERFACE diff --git a/simgear/structure/SGAtomic.cxx b/simgear/structure/SGAtomic.cxx index 728994df..3f0b9f44 100644 --- a/simgear/structure/SGAtomic.cxx +++ b/simgear/structure/SGAtomic.cxx @@ -17,10 +17,13 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ +#ifdef HAVE_CONFIG_H +# include +#endif #include "SGAtomic.hxx" -#if defined(SGATOMIC_USE_GCC4_BUILTINS) && defined (__i386__) +#if defined(SGATOMIC_USE_GCC4_BUILTINS) && !defined (GCC_ATOMIC_BUILTINS_FOUND) // Usually the appropriate functions are inlined by gcc. // But if gcc is called with something equivalent to -march=i386, From 6250f675db9fdd6f2aef7be43207cd0ac0b6baeb Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 23 Oct 2011 17:56:28 +0100 Subject: [PATCH 03/25] Fixes for headless mode. --- simgear/math/SGGeod.cxx | 4 ++++ simgear/math/project.cxx | 9 +++++++++ simgear/math/project.hxx | 7 +++++++ simgear/misc/PathOptions.cxx | 8 ++++++++ simgear/misc/PathOptions.hxx | 3 +++ simgear/misc/interpolator.cxx | 4 ++++ simgear/props/propertyObject_test.cxx | 3 +++ simgear/props/props_test.cxx | 4 ++++ simgear/structure/Singleton.hxx | 5 +++++ simgear/structure/event_mgr.cxx | 4 ++++ simgear/structure/subsystem_mgr.cxx | 4 ++++ simgear/timing/timezone.cxx | 4 ++++ 12 files changed, 59 insertions(+) diff --git a/simgear/math/SGGeod.cxx b/simgear/math/SGGeod.cxx index 15468707..20fa1938 100644 --- a/simgear/math/SGGeod.cxx +++ b/simgear/math/SGGeod.cxx @@ -15,6 +15,10 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // +#ifdef HAVE_CONFIG_H +# include +#endif + #include "SGMath.hxx" #ifndef NO_OPENSCENEGRAPH_INTERFACE diff --git a/simgear/math/project.cxx b/simgear/math/project.cxx index f1c2b143..c6a4ef73 100644 --- a/simgear/math/project.cxx +++ b/simgear/math/project.cxx @@ -15,8 +15,14 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // +#ifdef HAVE_CONFIG_H +# include +#endif + #include "project.hxx" +#ifndef NO_OPENSCENEGRAPH_INTERFACE + #include #include @@ -41,3 +47,6 @@ GLint project(GLdouble objX, GLdouble objY, GLdouble objZ, } } + +#endif // of NO_OPENSCENEGRAPH_INTERFACE + diff --git a/simgear/math/project.hxx b/simgear/math/project.hxx index 40353a2d..07a97d79 100644 --- a/simgear/math/project.hxx +++ b/simgear/math/project.hxx @@ -16,6 +16,9 @@ // #ifndef SIMGEAR_PROJECT_HXX #define SIMGEAR_PROJECT_HXX 1 + +#ifndef NO_OPENSCENEGRAPH_INTERFACE + #include namespace simgear @@ -26,4 +29,8 @@ extern GLint project(GLdouble objX, GLdouble objY, GLdouble objZ, const GLint *view, GLdouble* winX, GLdouble* winY, GLdouble* winZ); } + +#endif // of NO_OPENSCENEGRAPH_INTERFACE + #endif + diff --git a/simgear/misc/PathOptions.cxx b/simgear/misc/PathOptions.cxx index 32c719d6..b81600d8 100644 --- a/simgear/misc/PathOptions.cxx +++ b/simgear/misc/PathOptions.cxx @@ -17,6 +17,12 @@ // // $Id$ +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifndef NO_OPENSCENEGRAPH_INTERFACE + #include #include "PathOptions.hxx" @@ -31,3 +37,5 @@ osgDB::ReaderWriter::Options* simgear::makeOptionsFromPath(const SGPath& path) options->setDatabasePath(path.str()); return options; } + +#endif // of NO_OPENSCENEGRAPH_INTERFACE diff --git a/simgear/misc/PathOptions.hxx b/simgear/misc/PathOptions.hxx index 9b14d6e8..8d4186a7 100644 --- a/simgear/misc/PathOptions.hxx +++ b/simgear/misc/PathOptions.hxx @@ -20,6 +20,7 @@ #ifndef PATHOPTIONSHXX #define PATHOPTIONSHXX 1 +#ifndef NO_OPENSCENEGRAPH_INTERFACE #include #include @@ -28,3 +29,5 @@ namespace simgear osgDB::ReaderWriter::Options* makeOptionsFromPath(const SGPath&); } #endif + +#endif diff --git a/simgear/misc/interpolator.cxx b/simgear/misc/interpolator.cxx index 2e902cae..04a898cc 100644 --- a/simgear/misc/interpolator.cxx +++ b/simgear/misc/interpolator.cxx @@ -16,6 +16,10 @@ // 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 +#endif + #include "interpolator.hxx" #include diff --git a/simgear/props/propertyObject_test.cxx b/simgear/props/propertyObject_test.cxx index 5bb4ae58..b07bb483 100644 --- a/simgear/props/propertyObject_test.cxx +++ b/simgear/props/propertyObject_test.cxx @@ -1,3 +1,6 @@ +#ifdef HAVE_CONFIG_H +# include +#endif #include diff --git a/simgear/props/props_test.cxx b/simgear/props/props_test.cxx index cd54ec50..f8299263 100644 --- a/simgear/props/props_test.cxx +++ b/simgear/props/props_test.cxx @@ -3,6 +3,10 @@ // Test harness. //////////////////////////////////////////////////////////////////////// +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include diff --git a/simgear/structure/Singleton.hxx b/simgear/structure/Singleton.hxx index 0c3a5946..cc98c497 100644 --- a/simgear/structure/Singleton.hxx +++ b/simgear/structure/Singleton.hxx @@ -3,8 +3,10 @@ #include +#ifndef NO_OPENSCENEGRAPH_INTERFACE #include #include +#endif namespace simgear { @@ -27,6 +29,7 @@ public: } }; +#ifndef NO_OPENSCENEGRAPH_INTERFACE template class SingletonRefPtr { @@ -54,5 +57,7 @@ public: return SingletonRefPtr::instance(); } }; +#endif // of NO_OPENSCENEGRAPH_INTERFACE + } #endif diff --git a/simgear/structure/event_mgr.cxx b/simgear/structure/event_mgr.cxx index 11b34b7a..f448a649 100644 --- a/simgear/structure/event_mgr.cxx +++ b/simgear/structure/event_mgr.cxx @@ -1,3 +1,7 @@ +#ifdef HAVE_CONFIG_H +# include +#endif + #include "event_mgr.hxx" #include diff --git a/simgear/structure/subsystem_mgr.cxx b/simgear/structure/subsystem_mgr.cxx index 39598abe..a59d6ef0 100644 --- a/simgear/structure/subsystem_mgr.cxx +++ b/simgear/structure/subsystem_mgr.cxx @@ -18,6 +18,10 @@ // // $Id$ +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include diff --git a/simgear/timing/timezone.cxx b/simgear/timing/timezone.cxx index 7f09e6c6..11884918 100644 --- a/simgear/timing/timezone.cxx +++ b/simgear/timing/timezone.cxx @@ -26,6 +26,10 @@ * ************************************************************************/ +#ifdef HAVE_CONFIG_H +# include +#endif + #include #include #include From 83772c87ac3f4dc8d18a8a4e9a28948ba8b2037c Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Sun, 23 Oct 2011 23:03:15 +0200 Subject: [PATCH 04/25] Rework SGAtomic, move more into the implementation. Mainly move many cases into the implementation file. --- simgear/structure/SGAtomic.cxx | 120 ++++++++++++++++++++++----------- simgear/structure/SGAtomic.hxx | 88 ++++++++++++------------ 2 files changed, 127 insertions(+), 81 deletions(-) diff --git a/simgear/structure/SGAtomic.cxx b/simgear/structure/SGAtomic.cxx index 3f0b9f44..68fcf775 100644 --- a/simgear/structure/SGAtomic.cxx +++ b/simgear/structure/SGAtomic.cxx @@ -1,6 +1,6 @@ /* -*-c++-*- * - * Copyright (C) 2005-2009 Mathias Froehlich + * Copyright (C) 2005-2009,2011 Mathias Froehlich * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -17,62 +17,104 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * */ + #ifdef HAVE_CONFIG_H # include #endif #include "SGAtomic.hxx" -#if defined(SGATOMIC_USE_GCC4_BUILTINS) && !defined (GCC_ATOMIC_BUILTINS_FOUND) +#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS) -// Usually the appropriate functions are inlined by gcc. -// But if gcc is called with something equivalent to -march=i386, -// it will not assume that there is a lock instruction and instead -// calls this pair of functions. We will provide them here in this case. -// Note that this assembler code will not work on a i386 chip anymore. -// But I firmly believe that we can assume to run at least on a i486 ... +#if defined(_WIN32) +# include +#elif defined(GCC_ATOMIC_BUILTINS_FOUND) +#elif defined(__GNUC__) && defined(__i386__) +#else +# include +#endif -extern "C" { - -unsigned __sync_sub_and_fetch_4(volatile void *ptr, unsigned value) +unsigned +SGAtomic::operator++() { - register volatile unsigned* mem = reinterpret_cast(ptr); - register unsigned result; - __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}" - : "=r" (result), "=m" (*mem) - : "0" (-value), "m" (*mem) - : "memory"); - return result - value; +#if defined(_WIN32) + return InterlockedIncrement(reinterpret_cast(&mValue)); +#elif defined(GCC_ATOMIC_BUILTINS_FOUND) + return __sync_add_and_fetch(&mValue, 1); +#elif defined(__GNUC__) && defined(__i386__) + register volatile unsigned* mem = reinterpret_cast(&mValue); + register unsigned result; + __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}" + : "=r" (result), "=m" (*mem) + : "0" (1), "m" (*mem) + : "memory"); + return result + 1; +#else + SGGuard lock(mMutex); + return ++mValue; +#endif } -unsigned __sync_add_and_fetch_4(volatile void *ptr, unsigned value) +unsigned +SGAtomic::operator--() { - register volatile unsigned* mem = reinterpret_cast(ptr); - register unsigned result; - __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}" - : "=r" (result), "=m" (*mem) - : "0" (value), "m" (*mem) - : "memory"); - return result + value; +#if defined(_WIN32) + return InterlockedDecrement(reinterpret_cast(&mValue)); +#elif defined(GCC_ATOMIC_BUILTINS_FOUND) + return __sync_sub_and_fetch(&mValue, 1); +#elif defined(__GNUC__) && defined(__i386__) + register volatile unsigned* mem = reinterpret_cast(&mValue); + register unsigned result; + __asm__ __volatile__("lock; xadd{l} {%0,%1|%1,%0}" + : "=r" (result), "=m" (*mem) + : "0" (-1), "m" (*mem) + : "memory"); + return result - 1; +#else + SGGuard lock(mMutex); + return --mValue; +#endif } -unsigned __sync_bool_compare_and_swap_4(volatile void *ptr, - unsigned oldValue, unsigned newValue) +SGAtomic::operator unsigned() const { - register volatile unsigned* mem = reinterpret_cast(ptr); - unsigned before; - __asm__ __volatile__("lock; cmpxchg{l} {%1,%2|%1,%2}" - : "=a"(before) - : "q"(newValue), "m"(*mem), "0"(oldValue) - : "memory"); - return before == oldValue; +#if defined(_WIN32) + return static_cast(mValue); +#elif defined(GCC_ATOMIC_BUILTINS_FOUND) + __sync_synchronize(); + return mValue; +#elif defined(__GNUC__) && defined(__i386__) + __asm__ __volatile__("": : : "memory"); + return mValue; +#else + SGGuard lock(mMutex); + return mValue; +#endif } -void __sync_synchronize() +bool +SGAtomic::compareAndExchange(unsigned oldValue, unsigned newValue) { - __asm__ __volatile__("": : : "memory"); +#if defined(_WIN32) + long volatile* lvPtr = reinterpret_cast(&mValue); + return oldValue == InterlockedCompareExchange(lvPtr, newValue, oldValue); +#elif defined(GCC_ATOMIC_BUILTINS_FOUND) + return __sync_bool_compare_and_swap(&mValue, oldValue, newValue); +#elif defined(__GNUC__) && defined(__i386__) + register volatile unsigned* mem = reinterpret_cast(&mValue); + unsigned before; + __asm__ __volatile__("lock; cmpxchg{l} {%1,%2|%1,%2}" + : "=a"(before) + : "q"(newValue), "m"(*mem), "0"(oldValue) + : "memory"); + return before == oldValue; +#else + SGGuard lock(mMutex); + if (mValue != oldValue) + return false; + mValue = newValue; + return true; +#endif } -} // extern "C" - #endif diff --git a/simgear/structure/SGAtomic.hxx b/simgear/structure/SGAtomic.hxx index 081a4906..91bb262e 100644 --- a/simgear/structure/SGAtomic.hxx +++ b/simgear/structure/SGAtomic.hxx @@ -1,6 +1,6 @@ /* -*-c++-*- * - * Copyright (C) 2005-2009 Mathias Froehlich + * Copyright (C) 2005-2009,2011 Mathias Froehlich * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -21,85 +21,89 @@ #ifndef SGAtomic_HXX #define SGAtomic_HXX -#if defined(__GNUC__) && ((4 < __GNUC__)||(4 == __GNUC__ && 1 <= __GNUC_MINOR__)) \ - && (defined(__i386__) || defined(__x86_64__)) +#if defined(__GNUC__) && ((4 < __GNUC__)||(4 == __GNUC__ && 1 <= __GNUC_MINOR__)) && \ + defined(__x86_64__) // No need to include something. Is a Compiler API ... # define SGATOMIC_USE_GCC4_BUILTINS +#elif defined(__GNUC__) && defined(__i386__) +# define SGATOMIC_USE_LIBRARY_FUNCTIONS #elif defined(__sgi) && defined(_COMPILER_VERSION) && (_COMPILER_VERSION>=730) // No need to include something. Is a Compiler API ... # define SGATOMIC_USE_MIPSPRO_BUILTINS #elif defined(_WIN32) -# include -# define SGATOMIC_USE_WIN32_INTERLOCKED +# define SGATOMIC_USE_LIBRARY_FUNCTIONS #else // The sledge hammer ... +# define SGATOMIC_USE_LIBRARY_FUNCTIONS # include -# include #endif class SGAtomic { public: SGAtomic(unsigned value = 0) : mValue(value) { } + +#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS) + unsigned operator++(); +#else unsigned operator++() { -#if defined(SGATOMIC_USE_GCC4_BUILTINS) +# if defined(SGATOMIC_USE_GCC4_BUILTINS) return __sync_add_and_fetch(&mValue, 1); -#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) +# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) return __add_and_fetch(&mValue, 1); -#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED) - return InterlockedIncrement(reinterpret_cast(&mValue)); -#else - SGGuard lock(mMutex); - return ++mValue; -#endif +# else +# error +# endif } +#endif + +#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS) + unsigned operator--(); +#else unsigned operator--() { -#if defined(SGATOMIC_USE_GCC4_BUILTINS) +# if defined(SGATOMIC_USE_GCC4_BUILTINS) return __sync_sub_and_fetch(&mValue, 1); -#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) +# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) return __sub_and_fetch(&mValue, 1); -#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED) - return InterlockedDecrement(reinterpret_cast(&mValue)); -#else - SGGuard lock(mMutex); - return --mValue; -#endif +# else +# error +# endif } +#endif + +#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS) + operator unsigned() const; +#else operator unsigned() const { -#if defined(SGATOMIC_USE_GCC4_BUILTINS) +# if defined(SGATOMIC_USE_GCC4_BUILTINS) __sync_synchronize(); return mValue; -#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) +# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) __synchronize(); return mValue; -#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED) - return static_cast(mValue); -#else - SGGuard lock(mMutex); - return mValue; -#endif +# else +# error +# endif } +#endif +#if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS) + bool compareAndExchange(unsigned oldValue, unsigned newValue); +#else bool compareAndExchange(unsigned oldValue, unsigned newValue) { -#if defined(SGATOMIC_USE_GCC4_BUILTINS) +# if defined(SGATOMIC_USE_GCC4_BUILTINS) return __sync_bool_compare_and_swap(&mValue, oldValue, newValue); -#elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) +# elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) return __compare_and_swap(&mValue, oldValue, newValue); -#elif defined(SGATOMIC_USE_WIN32_INTERLOCKED) - long volatile* lvPtr = reinterpret_cast(&mValue); - return oldValue == InterlockedCompareExchange(lvPtr, newValue, oldValue); -#else - SGGuard lock(mMutex); - if (mValue != oldValue) - return false; - mValue = newValue; - return true; -#endif +# else +# error +# endif } +#endif private: SGAtomic(const SGAtomic&); From 7438aea8697802595dc5faf662606317b75f995c Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Sun, 23 Oct 2011 23:27:38 +0200 Subject: [PATCH 05/25] Fix SGAtomic mutex logic. --- simgear/structure/SGAtomic.cxx | 4 +++- simgear/structure/SGAtomic.hxx | 5 ++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/simgear/structure/SGAtomic.cxx b/simgear/structure/SGAtomic.cxx index 68fcf775..71f24ed9 100644 --- a/simgear/structure/SGAtomic.cxx +++ b/simgear/structure/SGAtomic.cxx @@ -30,8 +30,10 @@ # include #elif defined(GCC_ATOMIC_BUILTINS_FOUND) #elif defined(__GNUC__) && defined(__i386__) -#else +#elif defined(SGATOMIC_USE_MUTEX) # include +#else +# error #endif unsigned diff --git a/simgear/structure/SGAtomic.hxx b/simgear/structure/SGAtomic.hxx index 91bb262e..493c8d25 100644 --- a/simgear/structure/SGAtomic.hxx +++ b/simgear/structure/SGAtomic.hxx @@ -35,6 +35,7 @@ #else // The sledge hammer ... # define SGATOMIC_USE_LIBRARY_FUNCTIONS +# define SGATOMIC_USE_MUTEX # include #endif @@ -109,9 +110,7 @@ private: SGAtomic(const SGAtomic&); SGAtomic& operator=(const SGAtomic&); -#if !defined(SGATOMIC_USE_GCC4_BUILTINS) \ - && !defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) \ - && !defined(SGATOMIC_USE_WIN32_INTERLOCKED) +#if defined(SGATOMIC_USE_MUTEX) mutable SGMutex mMutex; #endif unsigned mValue; From 2fb13c76f562f19e99c68c79c2055a171d91311e Mon Sep 17 00:00:00 2001 From: James Turner Date: Mon, 24 Oct 2011 18:09:42 +0100 Subject: [PATCH 06/25] Address warnings found via Clang - especially related to destructor visibility with ref_ptrs of various kinds. --- simgear/scene/material/EffectBuilder.cxx | 10 ++++++++++ simgear/scene/material/EffectBuilder.hxx | 3 +++ simgear/scene/tgdb/obj.cxx | 4 ++-- simgear/scene/util/StateAttributeFactory.cxx | 6 ++++++ simgear/scene/util/StateAttributeFactory.hxx | 2 ++ simgear/sound/sample_openal.hxx | 2 +- 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/simgear/scene/material/EffectBuilder.cxx b/simgear/scene/material/EffectBuilder.cxx index 338fc9aa..79ebb248 100644 --- a/simgear/scene/material/EffectBuilder.cxx +++ b/simgear/scene/material/EffectBuilder.cxx @@ -102,4 +102,14 @@ namespace effect { const char* colorFields[] = {"red", "green", "blue", "alpha"}; } + +PassAttributeBuilder::~PassAttributeBuilder() +{ } + +} // of namespace simgear + + + + + diff --git a/simgear/scene/material/EffectBuilder.hxx b/simgear/scene/material/EffectBuilder.hxx index a30efa5e..3165ae18 100644 --- a/simgear/scene/material/EffectBuilder.hxx +++ b/simgear/scene/material/EffectBuilder.hxx @@ -350,8 +350,11 @@ protected: struct PassAttrMapSingleton : public simgear::Singleton { PassAttrMap passAttrMap; + }; public: + virtual ~PassAttributeBuilder(); // anchor into the compilation unit. + virtual void buildAttribute(Effect* effect, Pass* pass, const SGPropertyNode* prop, const SGReaderWriterXMLOptions* options) diff --git a/simgear/scene/tgdb/obj.cxx b/simgear/scene/tgdb/obj.cxx index 36011d72..6e16dc70 100644 --- a/simgear/scene/tgdb/obj.cxx +++ b/simgear/scene/tgdb/obj.cxx @@ -583,7 +583,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool { SGBinObject tile; if (!tile.read_bin(path)) - return false; + return NULL; SGVec3d center = tile.get_gbs_center(); SGGeod geodPos = SGGeod::fromCart(center); @@ -604,7 +604,7 @@ SGLoadBTG(const std::string& path, SGMaterialLib *matlib, bool calc_lights, bool SGTileGeometryBin tileGeometryBin; if (!tileGeometryBin.insertBinObj(tile, matlib)) - return false; + return NULL; SGVec3f up(0, 0, 1); GroundLightManager* lightManager = GroundLightManager::instance(); diff --git a/simgear/scene/util/StateAttributeFactory.cxx b/simgear/scene/util/StateAttributeFactory.cxx index 25a0a576..3e289ad5 100644 --- a/simgear/scene/util/StateAttributeFactory.cxx +++ b/simgear/scene/util/StateAttributeFactory.cxx @@ -86,4 +86,10 @@ StateAttributeFactory::StateAttributeFactory() _depthWritesDisabled->setDataVariance(Object::STATIC); } +// anchor the destructor into this file, to avoid ref_ptr warnings +StateAttributeFactory::~StateAttributeFactory() +{ + +} + } diff --git a/simgear/scene/util/StateAttributeFactory.hxx b/simgear/scene/util/StateAttributeFactory.hxx index 0076fa51..47603e7b 100644 --- a/simgear/scene/util/StateAttributeFactory.hxx +++ b/simgear/scene/util/StateAttributeFactory.hxx @@ -45,6 +45,8 @@ namespace simgear class StateAttributeFactory : public ReferencedSingleton { public: + ~StateAttributeFactory(); + // Alpha test > .01 osg::AlphaFunc* getStandardAlphaFunc() { return _standardAlphaFunc.get(); } // alpha source, 1 - alpha destination diff --git a/simgear/sound/sample_openal.hxx b/simgear/sound/sample_openal.hxx index b5267bb1..9e816c21 100644 --- a/simgear/sound/sample_openal.hxx +++ b/simgear/sound/sample_openal.hxx @@ -82,7 +82,7 @@ public: /** * Destructor */ - ~SGSoundSample (); + virtual ~SGSoundSample (); /** * Detect wheter this audio sample holds the information of a sound file. From 59ecf48b72a39b270db4c707d1460a9b867d275b Mon Sep 17 00:00:00 2001 From: James Turner Date: Tue, 25 Oct 2011 21:44:57 +0100 Subject: [PATCH 07/25] Support stream output by SGPath directly. --- simgear/misc/path_test.cxx | 2 +- simgear/misc/sg_path.hxx | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/simgear/misc/path_test.cxx b/simgear/misc/path_test.cxx index 2d789e64..4d976e01 100644 --- a/simgear/misc/path_test.cxx +++ b/simgear/misc/path_test.cxx @@ -27,7 +27,7 @@ using std::endl; void test_dir() { simgear::Dir temp = simgear::Dir::tempDir("foo"); - cout << "created:" << temp.path().str() << endl; + cout << "created:" << temp.path() << endl; VERIFY(temp.exists()); VERIFY(temp.path().isDir()); diff --git a/simgear/misc/sg_path.hxx b/simgear/misc/sg_path.hxx index e71c5f54..c19b977d 100644 --- a/simgear/misc/sg_path.hxx +++ b/simgear/misc/sg_path.hxx @@ -236,6 +236,13 @@ private: mutable time_t _modTime; }; +/// Output to an ostream +template +inline +std::basic_ostream& +operator<<(std::basic_ostream& s, const SGPath& p) +{ return s << "Path \"" << p.str() << "\""; } + /** * Split a directory string into a list of it's parent directories. From 75b695664a8acce3a48f369c67c8302181aeb160 Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 26 Oct 2011 19:57:57 +0100 Subject: [PATCH 08/25] Change (revert!) behaviour of SGPath::base, which broke TerraGear, when used with multiple file suffixes (hgt.zip, for example). Test cases updated to match TG-required behaviour. --- simgear/misc/path_test.cxx | 4 ++-- simgear/misc/sg_path.cxx | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/simgear/misc/path_test.cxx b/simgear/misc/path_test.cxx index 4d976e01..cda48859 100644 --- a/simgear/misc/path_test.cxx +++ b/simgear/misc/path_test.cxx @@ -82,7 +82,7 @@ int main(int argc, char* argv[]) SGPath pj("/Foo/zot.dot/thing.tar.gz"); COMPARE(pj.dir(), std::string("/Foo/zot.dot")); COMPARE(pj.file(), std::string("thing.tar.gz")); - COMPARE(pj.base(), std::string("/Foo/zot.dot/thing")); + COMPARE(pj.base(), std::string("/Foo/zot.dot/thing.tar")); COMPARE(pj.file_base(), std::string("thing")); COMPARE(pj.extension(), std::string("gz")); COMPARE(pj.complete_lower_extension(), std::string("tar.gz")); @@ -124,7 +124,7 @@ int main(int argc, char* argv[]) SGPath extB("BAH/FOO.HTML.GZ"); COMPARE(extB.extension(), "GZ"); - COMPARE(extB.base(), "BAH/FOO"); + COMPARE(extB.base(), "BAH/FOO.HTML"); COMPARE(extB.lower_extension(), "gz"); COMPARE(extB.complete_lower_extension(), "html.gz"); #ifdef _WIN32 diff --git a/simgear/misc/sg_path.cxx b/simgear/misc/sg_path.cxx index bff1a61c..2a98b34e 100644 --- a/simgear/misc/sg_path.cxx +++ b/simgear/misc/sg_path.cxx @@ -189,40 +189,40 @@ string SGPath::file() const { string SGPath::dir() const { int index = path.rfind(sgDirPathSep); if (index >= 0) { - return path.substr(0, index); + return path.substr(0, index); } else { - return ""; + return ""; } } // get the base part of the path (everything but the extension.) -string SGPath::base() const { - unsigned int index = path.rfind(sgDirPathSep); - if (index == string::npos) { - index = 0; // no separator in the name - } else { - ++index; // skip past the separator - } - -// find the first dot after the final separator - unsigned int firstDot = path.find(".", index); - if (firstDot == string::npos) { - return path; // no extension, return whole path +string SGPath::base() const +{ + string::size_type index = path.rfind("."); + string::size_type lastSep = path.rfind(sgDirPathSep); + +// tolerate dots inside directory names + if ((lastSep != string::npos) && (index < lastSep)) { + return path; } - return path.substr(0, firstDot); + if (index >= 0) { + return path.substr(0, index); + } else { + return path; + } } string SGPath::file_base() const { - unsigned int index = path.rfind(sgDirPathSep); + string::size_type index = path.rfind(sgDirPathSep); if (index == string::npos) { index = 0; // no separator in the name } else { ++index; // skip past the separator } - unsigned int firstDot = path.find(".", index); + string::size_type firstDot = path.find(".", index); if (firstDot == string::npos) { return path.substr(index); // no extensions } @@ -248,14 +248,14 @@ string SGPath::lower_extension() const { string SGPath::complete_lower_extension() const { - unsigned int index = path.rfind(sgDirPathSep); + string::size_type index = path.rfind(sgDirPathSep); if (index == string::npos) { index = 0; // no separator in the name } else { ++index; // skip past the separator } - int firstDot = path.find(".", index); + string::size_type firstDot = path.find(".", index); if ((firstDot >= 0) && (path.find(sgDirPathSep, firstDot) == string::npos)) { return boost::to_lower_copy(path.substr(firstDot + 1)); } else { From c6d5cbd52c4c02e453bb07d9951a059336c6532c Mon Sep 17 00:00:00 2001 From: Torsten Dreyer Date: Thu, 27 Oct 2011 08:18:54 +0200 Subject: [PATCH 09/25] Keep VC90 project file working with SGAtomic --- projects/VC90/SimGear.vcproj | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/projects/VC90/SimGear.vcproj b/projects/VC90/SimGear.vcproj index 077af7ae..6c244843 100644 --- a/projects/VC90/SimGear.vcproj +++ b/projects/VC90/SimGear.vcproj @@ -1499,6 +1499,14 @@ + + + + From 95ddc04a734d56d917c94e4bc952e9ac78637ba6 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 28 Oct 2011 12:07:35 +0100 Subject: [PATCH 10/25] Fix assorted compiler warnings found by Clang --- simgear/io/HTTPRequest.cxx | 2 +- simgear/io/iochannel.cxx | 2 +- simgear/io/iochannel.hxx | 2 +- simgear/io/sg_file.hxx | 2 +- simgear/misc/sg_path.cxx | 4 ++-- simgear/misc/sg_path.hxx | 2 +- simgear/misc/zfstream.cxx | 2 +- simgear/misc/zfstream.hxx | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/simgear/io/HTTPRequest.cxx b/simgear/io/HTTPRequest.cxx index 4b7a11bf..38651a3e 100644 --- a/simgear/io/HTTPRequest.cxx +++ b/simgear/io/HTTPRequest.cxx @@ -66,7 +66,7 @@ void Request::responseStart(const string& r) void Request::responseHeader(const string& key, const string& value) { if (key == "connection") { - _willClose = (value.find("close") >= 0); + _willClose = (value.find("close") != string::npos); } _responseHeaders[key] = value; diff --git a/simgear/io/iochannel.cxx b/simgear/io/iochannel.cxx index 9b88c6d5..468f666b 100644 --- a/simgear/io/iochannel.cxx +++ b/simgear/io/iochannel.cxx @@ -73,6 +73,6 @@ bool SGIOChannel::close() { // dummy eof routine -bool SGIOChannel::eof() { +bool SGIOChannel::eof() const { return false; } diff --git a/simgear/io/iochannel.hxx b/simgear/io/iochannel.hxx index ea1b0077..f5266b03 100644 --- a/simgear/io/iochannel.hxx +++ b/simgear/io/iochannel.hxx @@ -149,7 +149,7 @@ public: * false. * @return result of eof check */ - virtual bool eof(); + virtual bool eof() const; inline void set_type( SGChannelType t ) { type = t; } inline SGChannelType get_type() const { return type; } diff --git a/simgear/io/sg_file.hxx b/simgear/io/sg_file.hxx index 7e5854c1..7d842863 100644 --- a/simgear/io/sg_file.hxx +++ b/simgear/io/sg_file.hxx @@ -88,7 +88,7 @@ public: inline std::string get_file_name() const { return file_name; } /** @return true of eof conditions exists */ - inline bool eof() const { return eof_flag; }; + virtual bool eof() const { return eof_flag; }; }; diff --git a/simgear/misc/sg_path.cxx b/simgear/misc/sg_path.cxx index 2a98b34e..ed31e18b 100644 --- a/simgear/misc/sg_path.cxx +++ b/simgear/misc/sg_path.cxx @@ -206,7 +206,7 @@ string SGPath::base() const return path; } - if (index >= 0) { + if (index != string::npos) { return path.substr(0, index); } else { return path; @@ -256,7 +256,7 @@ string SGPath::complete_lower_extension() const } string::size_type firstDot = path.find(".", index); - if ((firstDot >= 0) && (path.find(sgDirPathSep, firstDot) == string::npos)) { + if ((firstDot != string::npos) && (path.find(sgDirPathSep, firstDot) == string::npos)) { return boost::to_lower_copy(path.substr(firstDot + 1)); } else { return ""; diff --git a/simgear/misc/sg_path.hxx b/simgear/misc/sg_path.hxx index c19b977d..969eec0b 100644 --- a/simgear/misc/sg_path.hxx +++ b/simgear/misc/sg_path.hxx @@ -124,7 +124,7 @@ public: std::string dir() const; /** - * Get the base part of the path (everything but the extension.) + * Get the base part of the path (everything but the final extension.) * @return the base string */ std::string base() const; diff --git a/simgear/misc/zfstream.cxx b/simgear/misc/zfstream.cxx index 9ad2dd77..0b75eb55 100644 --- a/simgear/misc/zfstream.cxx +++ b/simgear/misc/zfstream.cxx @@ -167,7 +167,7 @@ gzfilebuf::close() std::streampos -gzfilebuf::seekoff( std::streamoff, ios_seekdir, int ) +gzfilebuf::seekoff( std::streamoff, ios_seekdir, ios_openmode ) { return std::streampos(EOF); } diff --git a/simgear/misc/zfstream.hxx b/simgear/misc/zfstream.hxx index a8635483..a9f065ea 100644 --- a/simgear/misc/zfstream.hxx +++ b/simgear/misc/zfstream.hxx @@ -90,7 +90,7 @@ public: bool is_open() const { return (file != NULL); } /** @return stream position */ - virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, int which ); + virtual std::streampos seekoff( std::streamoff off, ios_seekdir way, ios_openmode which ); /** sync the stream */ virtual int sync(); From e34f597fe2ffe9f4a05bb66623cc8d8e06c433f0 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 28 Oct 2011 12:29:26 +0100 Subject: [PATCH 11/25] Add sound test programs to the CMake build. --- simgear/sound/CMakeLists.txt | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/simgear/sound/CMakeLists.txt b/simgear/sound/CMakeLists.txt index c07a7065..6670190a 100644 --- a/simgear/sound/CMakeLists.txt +++ b/simgear/sound/CMakeLists.txt @@ -16,4 +16,22 @@ set(SOURCES xmlsound.cxx ) -simgear_component(sound sound "${SOURCES}" "${HEADERS}") \ No newline at end of file +simgear_component(sound sound "${SOURCES}" "${HEADERS}") + +set(SOUND_TEST_LIBS + sgsound sgio sgmath sgstructure sgthreads sgtiming sgmisc sgdebug + ${CMAKE_THREAD_LIBS_INIT} + ${RT_LIBRARY} + ${ALUT_LIBRARY} ${OPENAL_LIBRARY}) + +function(create_test TEST_NAME) + add_executable(${TEST_NAME} ${TEST_NAME}.cxx) + target_link_libraries(${TEST_NAME} ${SOUND_TEST_LIBS}) + set_target_properties(${TEST_NAME} PROPERTIES + COMPILE_DEFINITIONS "SRC_DIR=\"${CMAKE_CURRENT_SOURCE_DIR}\"" ) +endfunction() + +create_test(openal_test1) +create_test(openal_test2) +create_test(openal_test3) +create_test(openal_test4) From f14ffd5b1db1c243d47eccd2a37c71f719c33681 Mon Sep 17 00:00:00 2001 From: James Turner Date: Fri, 28 Oct 2011 12:57:07 +0100 Subject: [PATCH 12/25] Fix a bug affecting TerraGear, and extend unit-tests to cover this. (SGPath::file returned an empty string for paths with no directory separator) --- simgear/misc/path_test.cxx | 8 ++++++++ simgear/misc/sg_path.cxx | 11 ++++++----- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/simgear/misc/path_test.cxx b/simgear/misc/path_test.cxx index cda48859..459f064c 100644 --- a/simgear/misc/path_test.cxx +++ b/simgear/misc/path_test.cxx @@ -135,6 +135,14 @@ int main(int argc, char* argv[]) #else COMPARE(d1.str_native(), std::string("/usr/local")); #endif + +// paths with only the file components + SGPath pf("something.txt.gz"); + COMPARE(pf.base(), "something.txt"); + COMPARE(pf.file(), "something.txt.gz"); + COMPARE(pf.dir(), ""); + COMPARE(pf.lower_extension(), "gz"); + COMPARE(pf.complete_lower_extension(), "txt.gz"); test_dir(); diff --git a/simgear/misc/sg_path.cxx b/simgear/misc/sg_path.cxx index ed31e18b..46e80228 100644 --- a/simgear/misc/sg_path.cxx +++ b/simgear/misc/sg_path.cxx @@ -175,12 +175,13 @@ void SGPath::concat( const string& p ) { // Get the file part of the path (everything after the last path sep) -string SGPath::file() const { - int index = path.rfind(sgDirPathSep); - if (index >= 0) { - return path.substr(index + 1); +string SGPath::file() const +{ + string::size_type index = path.rfind(sgDirPathSep); + if (index != string::npos) { + return path.substr(index + 1); } else { - return ""; + return path; } } From cd773e476407386a138ec1f9f6e46327f60e81a4 Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Fri, 28 Oct 2011 16:52:46 +0200 Subject: [PATCH 13/25] Add sleep implementations to SGTimeStamp. Implement sleeping to an absolute timestamp as well as sleeping for a relative time in SGtimeStamp. The reason for including this into SGTimeStamp is that the timestamps internals are required to do accurate sleeps to and absolute timestamp for the posix timer implementation. --- simgear/timing/timestamp.cxx | 217 ++++++++++++++++++++++++++++++++--- simgear/timing/timestamp.hxx | 18 +++ 2 files changed, 218 insertions(+), 17 deletions(-) diff --git a/simgear/timing/timestamp.cxx b/simgear/timing/timestamp.cxx index 83eff2fc..a2eae9ee 100644 --- a/simgear/timing/timestamp.cxx +++ b/simgear/timing/timestamp.cxx @@ -58,6 +58,29 @@ #include "timestamp.hxx" +#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS) +static clockid_t getClockId() +{ +#if defined(_POSIX_MONOTONIC_CLOCK) + static clockid_t clockid = CLOCK_MONOTONIC; + static bool firstTime = true; + if (!firstTime) + return clockid; + + firstTime = false; + // For the first time test if the monotonic clock is available. + // If so use this, if not use the realtime clock. + struct timespec ts; + if (-1 == clock_gettime(clockid, &ts) && errno == EINVAL) + clockid = CLOCK_REALTIME; + return clockid; +#else + return CLOCK_REALTIME; +#endif +} + +#endif + void SGTimeStamp::stamp() { #ifdef _WIN32 unsigned int t; @@ -66,27 +89,12 @@ void SGTimeStamp::stamp() { _nsec = ( t - ( _sec * 1000 ) ) * 1000 * 1000; #elif defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS) struct timespec ts; -#if defined(_POSIX_MONOTONIC_CLOCK) - static clockid_t clockid = CLOCK_MONOTONIC; - static bool firstTime = true; - if (firstTime) { - firstTime = false; - // For the first time test if the monotonic clock is available. - // If so use this if not use the realtime clock. - if (-1 == clock_gettime(clockid, &ts) && errno == EINVAL) - clockid = CLOCK_REALTIME; - } - clock_gettime(clockid, &ts); -#else - clock_gettime(CLOCK_REALTIME, &ts); -#endif + clock_gettime(getClockId(), &ts); _sec = ts.tv_sec; _nsec = ts.tv_nsec; #elif defined( HAVE_GETTIMEOFDAY ) struct timeval current; - struct timezone tz; - // sg_timestamp currtime; - gettimeofday(¤t, &tz); + gettimeofday(¤t, NULL); _sec = current.tv_sec; _nsec = current.tv_usec * 1000; #elif defined( HAVE_GETLOCALTIME ) @@ -104,6 +112,181 @@ void SGTimeStamp::stamp() { #endif } +// sleep based timing loop. +// +// Calling sleep, even usleep() on linux is less accurate than +// we like, but it does free up the cpu for other tasks during +// the sleep so it is desirable. Because of the way sleep() +// is implemented in consumer operating systems like windows +// and linux, you almost always sleep a little longer than the +// requested amount. +// +// To combat the problem of sleeping too long, we calculate the +// desired wait time and shorten it by 2000us (2ms) to avoid +// [hopefully] over-sleep'ing. The 2ms value was arrived at +// via experimentation. We follow this up at the end with a +// simple busy-wait loop to get the final pause timing exactly +// right. +// +// Assuming we don't oversleep by more than 2000us, this +// should be a reasonable compromise between sleep based +// waiting, and busy waiting. +// +// Usually posix timer resolutions are low enough that we +// could just leave this to the operating system today. +// The day where the busy loop was introduced in flightgear, +// the usual kernels still had just about 10ms (=HZ for +// the timer tick) accuracy which is too bad to catch 60Hz... +bool SGTimeStamp::sleepUntil(const SGTimeStamp& abstime) +{ +#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS) + SGTimeStamp abstimeForSleep = abstime; + + // Always undersleep by resolution of the clock + struct timespec ts; + if (-1 != clock_getres(getClockId(), &ts)) { + abstimeForSleep -= SGTimeStamp::fromSecNSec(ts.tv_sec, ts.tv_nsec); + } else { + abstimeForSleep -= SGTimeStamp::fromSecMSec(0, 2); + } + + ts.tv_sec = abstimeForSleep._sec; + ts.tv_nsec = abstimeForSleep._nsec; + for (;;) { + int ret = clock_nanosleep(getClockId(), TIMER_ABSTIME, &ts, NULL); + if (-1 == ret && errno != EINTR) + return false; + if (ret == 0) + break; + } + + // The busy loop for the rest + SGTimeStamp currentTime; + do { + currentTime.stamp(); + } while (currentTime < abstime); + + return true; + +#elif defined _WIN32 + + SGTimeStamp currentTime; + currentTime.stamp(); + if (abstime <= currentTime) + return true; + + SGTimeStamp abstimeForSleep = abstime - SGTimeStamp::fromSecMSec(0, 2); + for (;abstimeForSleep < currentTime;) { + SGTimeStamp timeDiff = abstimeForSleep - currentTime; + if (timeDiff < SGTimeStamp::fromSecMSec(0, 1)) + break; + // Don't know, but may be win32 has something better today?? + Sleep(static_cast(timeDiff.toMSecs())); + + currentTime.stamp(); + } + + // Follow by a busy loop + while (currentTime < abstime) { + currentTime.stamp(); + } + + return true; + +#else + + SGTimeStamp currentTime; + currentTime.stamp(); + if (abstime <= currentTime) + return true; + + SGTimeStamp abstimeForSleep = abstime - SGTimeStamp::fromSecMSec(0, 2); + for (;abstimeForSleep < currentTime;) { + SGTimeStamp timeDiff = abstimeForSleep - currentTime; + if (timeDiff < SGTimeStamp::fromSecUSec(0, 1)) + break; + // Its documented that some systems bail out on usleep for longer than 1s + // since we recheck the current time anyway just wait for + // less than a second multiple times + bool truncated = false; + if (SGTimeStamp::fromSec(1) < timeDiff) { + timeDiff = SGTimeStamp::fromSec(1); + truncated = true; + } + int ret = usleep(static_cast(timeDiff.toUSecs())); + if (-1 == ret && errno != EINTR) + return false; + if (ret == 0 && !truncated) + break; + + currentTime.stamp(); + } + + // Follow by a busy loop + while (currentTime < abstime) { + currentTime.stamp(); + } + + return true; + +#endif +} + +bool SGTimeStamp::sleepFor(const SGTimeStamp& reltime) +{ +#if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS) + struct timespec ts; + ts.tv_sec = reltime._sec; + ts.tv_nsec = reltime._nsec; + for (;;) { + struct timespec rem; + int ret = clock_nanosleep(getClockId(), 0, &ts, &rem); + if (-1 == ret && errno != EINTR) + return false; + if (ret == 0) + break; + // Use the remainder for the next cycle. + ts = rem; + } + return true; +#elif defined _WIN32 + if (reltime < SGTimeStamp::fromSecMSec(0, 1)) + return true; + // Don't know, but may be win32 has something better today?? + Sleep(static_cast(reltime.toMSecs())); + return true; +#else + SGTimeStamp abstime; + abstime.stamp(); + abstime += reltime; + + SGTimeStamp currentTime; + currentTime.stamp(); + for (;abstime < currentTime;) { + SGTimeStamp timeDiff = abstime - currentTime; + if (timeDiff < SGTimeStamp::fromSecUSec(0, 1)) + break; + // Its documented that some systems bail out on usleep for longer than 1s + // since we recheck the current time anyway just wait for + // less than a second multiple times + bool truncated = false; + if (SGTimeStamp::fromSec(1) < timeDiff) { + timeDiff = SGTimeStamp::fromSec(1); + truncated = true; + } + int ret = usleep(static_cast(timeDiff.toUSecs())); + if (-1 == ret && errno != EINTR) + return false; + if (ret == 0 && !truncated) + break; + + currentTime.stamp(); + } + + return true; +#endif +} + int SGTimeStamp::elapsedMSec() const { SGTimeStamp now; diff --git a/simgear/timing/timestamp.hxx b/simgear/timing/timestamp.hxx index f195dc37..ac9ca142 100644 --- a/simgear/timing/timestamp.hxx +++ b/simgear/timing/timestamp.hxx @@ -184,6 +184,8 @@ public: { SGTimeStamp ts; ts.setTime(sec); return ts; } static SGTimeStamp fromSec(const double& sec) { SGTimeStamp ts; ts.setTime(sec); return ts; } + static SGTimeStamp fromMSec(nsec_type msec) + { return SGTimeStamp(0, 1000*1000*msec); } static SGTimeStamp fromUSec(nsec_type usec) { return SGTimeStamp(0, 1000*usec); } static SGTimeStamp fromNSec(nsec_type nsec) @@ -195,6 +197,22 @@ public: static SGTimeStamp now() { SGTimeStamp ts; ts.stamp(); return ts; } + /** + * Sleep until the time of abstime is passed. + */ + static bool sleepUntil(const SGTimeStamp& abstime); + + /** + * Sleep for reltime. + */ + static bool sleepFor(const SGTimeStamp& reltime); + + /** + * Alias for the most common use case with milliseconds. + */ + static bool sleepForMSec(unsigned msec) + { return sleepFor(fromMSec(msec)); } + /** * elapsed time since the stamp was taken, in msec */ From 92db9682e04dbf727d590640e6ba8850b00b0bba Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Fri, 28 Oct 2011 16:58:29 +0200 Subject: [PATCH 14/25] Make use of SGTimeStamp::sleep*. --- simgear/io/httpget.cxx | 4 ++-- simgear/io/test_HTTP.cxx | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/simgear/io/httpget.cxx b/simgear/io/httpget.cxx index e10a29b4..b4934b8d 100644 --- a/simgear/io/httpget.cxx +++ b/simgear/io/httpget.cxx @@ -12,7 +12,7 @@ #include #include #include -#include +#include using namespace simgear; using std::cout; @@ -156,7 +156,7 @@ int main(int argc, char* argv[]) while (!req->complete()) { cl.update(); - sleepForMSec(100); + SGTimeStamp::sleepForMSec(100); } if (req->responseCode() != 200) { diff --git a/simgear/io/test_HTTP.cxx b/simgear/io/test_HTTP.cxx index 048cbb41..988f8bba 100644 --- a/simgear/io/test_HTTP.cxx +++ b/simgear/io/test_HTTP.cxx @@ -12,7 +12,6 @@ #include #include #include -#include using std::cout; using std::cerr; @@ -321,7 +320,7 @@ void waitForComplete(HTTP::Client* cl, TestRequest* tr) if (tr->complete) { return; } - sleepForMSec(1); + SGTimeStamp::sleepForMSec(1); } cerr << "timed out" << endl; @@ -335,7 +334,7 @@ void waitForFailed(HTTP::Client* cl, TestRequest* tr) if (tr->failed) { return; } - sleepForMSec(1); + SGTimeStamp::sleepForMSec(1); } cerr << "timed out waiting for failure" << endl; From d10bcc8a53ca36eac9afe14267d8fb67d547984f Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Fri, 28 Oct 2011 19:05:11 +0200 Subject: [PATCH 15/25] Hopefully fix jenkins build. --- simgear/sound/openal_test1.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/simgear/sound/openal_test1.cxx b/simgear/sound/openal_test1.cxx index 3d055b00..f02c53db 100644 --- a/simgear/sound/openal_test1.cxx +++ b/simgear/sound/openal_test1.cxx @@ -103,10 +103,10 @@ int main( int argc, char *argv[] ) { ALfloat source_vel[3]; // configuration values -// ALenum format; -// ALsizei size; -// ALvoid* data; -// ALsizei freq; + ALenum format; + ALsizei size; + ALvoid* data; + ALsizei freq; ALboolean loop = false; source_pos[0] = 0.0; source_pos[1] = 0.0; source_pos[2] = 0.0; From cc4b16b50dd4f2cc8b921f63d008945dc5f48857 Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Fri, 28 Oct 2011 19:10:20 +0200 Subject: [PATCH 16/25] Fix mac build. --- simgear/timing/timestamp.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/simgear/timing/timestamp.cxx b/simgear/timing/timestamp.cxx index a2eae9ee..2189d643 100644 --- a/simgear/timing/timestamp.cxx +++ b/simgear/timing/timestamp.cxx @@ -31,6 +31,7 @@ #include #include +#include #ifdef HAVE_SYS_TIMEB_H # include // for ftime() and struct timeb @@ -44,7 +45,6 @@ #if defined(_POSIX_TIMERS) && (0 < _POSIX_TIMERS) # include -# include #endif #ifdef WIN32 From 269299d9131934f413ae82e0bae9d6574febfe65 Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Fri, 28 Oct 2011 17:00:56 +0200 Subject: [PATCH 17/25] Remove sg_sleep.*. --- projects/VC90/SimGear.vcproj | 8 ----- simgear/misc/CMakeLists.txt | 2 -- simgear/misc/Makefile.am | 6 ++-- simgear/misc/sg_sleep.cxx | 60 ------------------------------------ simgear/misc/sg_sleep.hxx | 41 ------------------------ 5 files changed, 2 insertions(+), 115 deletions(-) delete mode 100644 simgear/misc/sg_sleep.cxx delete mode 100644 simgear/misc/sg_sleep.hxx diff --git a/projects/VC90/SimGear.vcproj b/projects/VC90/SimGear.vcproj index 6c244843..f3d50894 100644 --- a/projects/VC90/SimGear.vcproj +++ b/projects/VC90/SimGear.vcproj @@ -671,14 +671,6 @@ RelativePath="..\..\simgear\misc\sg_path.hxx" > - - - - diff --git a/simgear/misc/CMakeLists.txt b/simgear/misc/CMakeLists.txt index 7a06f3bd..43904321 100644 --- a/simgear/misc/CMakeLists.txt +++ b/simgear/misc/CMakeLists.txt @@ -7,7 +7,6 @@ set(HEADERS interpolator.hxx sg_dir.hxx sg_path.hxx - sg_sleep.hxx sgstream.hxx stdint.hxx stopwatch.hxx @@ -24,7 +23,6 @@ set(SOURCES interpolator.cxx sg_dir.cxx sg_path.cxx - sg_sleep.cxx sgstream.cxx strutils.cxx tabbed_values.cxx diff --git a/simgear/misc/Makefile.am b/simgear/misc/Makefile.am index ae696e79..e671418a 100644 --- a/simgear/misc/Makefile.am +++ b/simgear/misc/Makefile.am @@ -14,8 +14,7 @@ include_HEADERS = \ stdint.hxx \ PathOptions.hxx \ sg_dir.hxx \ - ResourceManager.hxx \ - sg_sleep.hxx + ResourceManager.hxx libsgmisc_a_SOURCES = \ sg_path.cxx \ @@ -27,8 +26,7 @@ libsgmisc_a_SOURCES = \ interpolator.cxx \ PathOptions.cxx \ sg_dir.cxx \ - ResourceManager.cxx \ - sg_sleep.cxx + ResourceManager.cxx #noinst_PROGRAMS = tabbed_value_test swap_test diff --git a/simgear/misc/sg_sleep.cxx b/simgear/misc/sg_sleep.cxx deleted file mode 100644 index a52880c5..00000000 --- a/simgear/misc/sg_sleep.cxx +++ /dev/null @@ -1,60 +0,0 @@ - -// Written by James Turner, started July 2010. -// -// Copyright (C) 2010 Curtis L. Olson - http://www.flightgear.org/~curt -// -// 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. -// -// $Id$ - -#include - -#ifdef SG_WINDOWS -# include -#else -# include -#endif - -namespace simgear -{ - -#ifdef SG_WINDOWS - -void sleepForSeconds(int seconds) -{ - Sleep(1000 * seconds); -} - -void sleepForMSec(int msec) -{ - Sleep(msec); -} - -#else - -void sleepForSeconds(int seconds) -{ - ::sleep(seconds); -} - -void sleepForMSec(int msec) -{ - ::usleep(msec * 1000); -} - -#endif - -} // of namespace simhear - diff --git a/simgear/misc/sg_sleep.hxx b/simgear/misc/sg_sleep.hxx deleted file mode 100644 index 389fdff3..00000000 --- a/simgear/misc/sg_sleep.hxx +++ /dev/null @@ -1,41 +0,0 @@ - -// Written by James Turner, started July 2010. -// -// Copyright (C) 2010 Curtis L. Olson - http://www.flightgear.org/~curt -// -// 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. -// -// $Id$ - - -#ifndef _SG_SLEEP_HXX -#define _SG_SLEEP_HXX - - -#include - - -namespace simgear -{ - -void sleepForSeconds(int seconds); - -void sleepForMSec(int msec); - -} // of namespace simgear - -#endif // _SG_SLEEP_HXX - - From 519a84334091adc73edf274052eac1ed6bf10815 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sat, 29 Oct 2011 11:06:24 +0100 Subject: [PATCH 18/25] Move ALUT 1.0 variables inside the #ifdef, to avoid some compiler warnings. --- simgear/sound/openal_test1.cxx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/simgear/sound/openal_test1.cxx b/simgear/sound/openal_test1.cxx index f02c53db..0a6dc885 100644 --- a/simgear/sound/openal_test1.cxx +++ b/simgear/sound/openal_test1.cxx @@ -103,10 +103,6 @@ int main( int argc, char *argv[] ) { ALfloat source_vel[3]; // configuration values - ALenum format; - ALsizei size; - ALvoid* data; - ALsizei freq; ALboolean loop = false; source_pos[0] = 0.0; source_pos[1] = 0.0; source_pos[2] = 0.0; @@ -131,6 +127,11 @@ int main( int argc, char *argv[] ) { } #else + ALenum format; + ALsizei size; + ALvoid* data; + ALsizei freq; + # if defined (__APPLE__) alutLoadWAVFile( (ALbyte *)AUDIOFILE, &format, &data, &size, &freq ); # else From a4b788980cf9235fe973bbac9012a935472ca06c Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Sat, 29 Oct 2011 21:13:12 +0200 Subject: [PATCH 19/25] Fix terrasync airport synchronization sequence Airport A-J were skipped. Thanks to James for spotting this. Also corrects actual sync order. --- simgear/scene/tsync/terrasync.cxx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/simgear/scene/tsync/terrasync.cxx b/simgear/scene/tsync/terrasync.cxx index 0f99d4e5..ec2e5ca0 100644 --- a/simgear/scene/tsync/terrasync.cxx +++ b/simgear/scene/tsync/terrasync.cxx @@ -802,10 +802,11 @@ void SGTerraSync::setTileCache(TileCache* tile_cache) void SGTerraSync::syncAirportsModels() { - static const char bounds[] = "KZAJ"; - for( unsigned i = 0; i < sizeof(bounds)/sizeof(bounds[0])/2; i+= 2 ) + static const char* bounds = "MZAJKL"; // airport sync order: K-L, A-J, M-Z + // note "request" method uses LIFO order, i.e. processes most recent request first + for( unsigned i = 0; i < strlen(bounds)/2; i++ ) { - for ( char synced_other = bounds[i]; synced_other <= bounds[i+1]; synced_other++ ) + for ( char synced_other = bounds[2*i]; synced_other <= bounds[2*i+1]; synced_other++ ) { ostringstream dir; dir << "Airports/" << synced_other; From 3477e1a4f531ab4e3f9585ddd17bd99d985c94f6 Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Sat, 29 Oct 2011 21:15:29 +0200 Subject: [PATCH 20/25] terrasync improvements Detach from console to make "Ctrl-C" work for fgfs on Linux. Immediately start synchronization of current position when starting at run-time. --- simgear/scene/tsync/terrasync.cxx | 91 +++++++++++++++++++------------ 1 file changed, 57 insertions(+), 34 deletions(-) diff --git a/simgear/scene/tsync/terrasync.cxx b/simgear/scene/tsync/terrasync.cxx index ec2e5ca0..d48b39e9 100644 --- a/simgear/scene/tsync/terrasync.cxx +++ b/simgear/scene/tsync/terrasync.cxx @@ -486,7 +486,18 @@ bool SGTerraSync::SvnThread::syncTreeExternal(const char* dir) command = buf.str(); #endif SG_LOG(SG_TERRAIN,SG_DEBUG, "sync command '" << command << "'"); + +#ifdef SG_WINDOWS + // tbd: does Windows support "popen"? int rc = system( command.c_str() ); +#else + FILE* pipe = popen( command.c_str(), "r"); + int rc=-1; + // wait for external process to finish + if (pipe) + rc = pclose(pipe); +#endif + if (rc) { SG_LOG(SG_TERRAIN,SG_ALERT, @@ -701,12 +712,21 @@ void SGTerraSync::reinit() _svnThread->setExtSvnUtility(_terraRoot->getStringValue("ext-svn-utility","svn")); if (_svnThread->start()) + { syncAirportsModels(); + if (last_lat != NOWHERE && last_lon != NOWHERE) + { + // reschedule most recent position + int lat = last_lat; + int lon = last_lon; + last_lat = NOWHERE; + last_lon = NOWHERE; + schedulePosition(lat, lon); + } + } } _stalled_node->setBoolValue(_svnThread->_stalled); - last_lat = NOWHERE; - last_lon = NOWHERE; } void SGTerraSync::bind() @@ -897,46 +917,49 @@ void SGTerraSync::syncAreas( int lat, int lon, int lat_dir, int lon_dir ) bool SGTerraSync::schedulePosition(int lat, int lon) { + bool Ok = false; + // Ignore messages where the location does not change if ( lat != last_lat || lon != last_lon ) { - SG_LOG(SG_TERRAIN,SG_DEBUG, "Requesting scenery update for position " << - lat << "," << lon); - int lat_dir, lon_dir, dist; - if ( last_lat == NOWHERE || last_lon == NOWHERE ) + if (_svnThread->_running) { - lat_dir = lon_dir = 0; - } else - { - dist = lat - last_lat; - if ( dist != 0 ) + SG_LOG(SG_TERRAIN,SG_DEBUG, "Requesting scenery update for position " << + lat << "," << lon); + int lat_dir=0; + int lon_dir=0; + if ( last_lat != NOWHERE && last_lon != NOWHERE ) { - lat_dir = dist / abs(dist); - } - else - { - lat_dir = 0; - } - dist = lon - last_lon; - if ( dist != 0 ) - { - lon_dir = dist / abs(dist); - } else - { - lon_dir = 0; + int dist = lat - last_lat; + if ( dist != 0 ) + { + lat_dir = dist / abs(dist); + } + else + { + lat_dir = 0; + } + dist = lon - last_lon; + if ( dist != 0 ) + { + lon_dir = dist / abs(dist); + } else + { + lon_dir = 0; + } } + + SG_LOG(SG_TERRAIN,SG_DEBUG, "Scenery update for " << + "lat = " << lat << ", lon = " << lon << + ", lat_dir = " << lat_dir << ", " << + "lon_dir = " << lon_dir); + + syncAreas( lat, lon, lat_dir, lon_dir ); + Ok = true; } - - SG_LOG(SG_TERRAIN,SG_DEBUG, "Scenery update for " << - "lat = " << lat << ", lon = " << lon << - ", lat_dir = " << lat_dir << ", " << - "lon_dir = " << lon_dir); - - syncAreas( lat, lon, lat_dir, lon_dir ); - last_lat = lat; last_lon = lon; - return true; } - return false; + + return Ok; } From aa0e3e3c9fd6bf174493e4ab1e3c292fc924a4f0 Mon Sep 17 00:00:00 2001 From: ThorstenB Date: Sat, 29 Oct 2011 21:20:46 +0200 Subject: [PATCH 21/25] #453: Using = as Nasal function argument crashes FG Keep Nasal parser from crashing when "=" function misses a left-hand element, i.e. when parsing "sin(=)". (Or do people writing such terrible syntax deserve a crash? ;-) ). --- simgear/nasal/codegen.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/simgear/nasal/codegen.c b/simgear/nasal/codegen.c index d1c05ef6..059c1144 100644 --- a/simgear/nasal/codegen.c +++ b/simgear/nasal/codegen.c @@ -536,6 +536,9 @@ static void genAssign(struct Parser* p, struct Token* t) { struct Token *lv = LEFT(t), *rv = RIGHT(t); int len, dummy, var=0; + if (!lv) + naParseError(p, "bad assignment, missing variable", t->line); + else if(parListLen(lv) || (lv->type == TOK_VAR && parListLen(RIGHT(lv)))) { if(lv->type == TOK_VAR) { lv = RIGHT(lv); var = 1; } len = parListLen(lv); From ee06ec0c4058f2fa24417670df9d1a544bf8e34d Mon Sep 17 00:00:00 2001 From: Csaba Halasz Date: Sun, 30 Oct 2011 02:14:27 +0200 Subject: [PATCH 22/25] terrasync build fix: added #include for strlen --- simgear/scene/tsync/terrasync.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/simgear/scene/tsync/terrasync.cxx b/simgear/scene/tsync/terrasync.cxx index d48b39e9..800f278a 100644 --- a/simgear/scene/tsync/terrasync.cxx +++ b/simgear/scene/tsync/terrasync.cxx @@ -45,6 +45,7 @@ #include // atoi() atof() abs() system() #include // signal() +#include #include #include From 2e9896a9abb0889407491a6dfb036ae5f7079287 Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 30 Oct 2011 07:55:29 +0000 Subject: [PATCH 23/25] Enhancements to property-object support, add a default ctor and some typedefs. --- simgear/props/propertyObject.cxx | 7 +++++++ simgear/props/propertyObject.hxx | 6 ++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/simgear/props/propertyObject.cxx b/simgear/props/propertyObject.cxx index df3f81f9..ff87898e 100644 --- a/simgear/props/propertyObject.cxx +++ b/simgear/props/propertyObject.cxx @@ -34,6 +34,13 @@ void PropertyObjectBase::setDefaultRoot(SGPropertyNode* aRoot) { static_defaultRoot = aRoot; } + +PropertyObjectBase::PropertyObjectBase() : + _path(NULL), + _prop(NULL) +{ + +} PropertyObjectBase::PropertyObjectBase(const PropertyObjectBase& aOther) : _path(aOther._path), diff --git a/simgear/props/propertyObject.hxx b/simgear/props/propertyObject.hxx index 5cc1588b..a6d357f8 100644 --- a/simgear/props/propertyObject.hxx +++ b/simgear/props/propertyObject.hxx @@ -28,6 +28,8 @@ class PropertyObjectBase public: static void setDefaultRoot(SGPropertyNode* aRoot); + PropertyObjectBase(); + PropertyObjectBase(const PropertyObjectBase& aOther); PropertyObjectBase(const char* aChild); @@ -57,6 +59,8 @@ template class PropertyObject : PropertyObjectBase { public: + PropertyObject(); + /** * Create from path relative to the default root, and option default value */ @@ -220,11 +224,9 @@ private: } // of namespace simgear -/* typedef simgear::PropertyObject SGPropObjDouble; typedef simgear::PropertyObject SGPropObjBool; typedef simgear::PropertyObject SGPropObjString; typedef simgear::PropertyObject SGPropObjInt; -*/ #endif From d36e13e8eda5bd4008e2f1951817497992b1f98a Mon Sep 17 00:00:00 2001 From: James Turner Date: Sun, 30 Oct 2011 07:55:44 +0000 Subject: [PATCH 24/25] Make tiedpropertylist quieter. --- simgear/props/tiedpropertylist.hxx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/simgear/props/tiedpropertylist.hxx b/simgear/props/tiedpropertylist.hxx index f33478ac..7fb354c4 100644 --- a/simgear/props/tiedpropertylist.hxx +++ b/simgear/props/tiedpropertylist.hxx @@ -51,7 +51,7 @@ public: template SGPropertyNode_ptr Tie( SGPropertyNode_ptr node, const SGRawValue &rawValue, bool useDefault = true ) { bool success = node->tie( rawValue, useDefault ); if( success ) { - SG_LOG( SG_ALL, SG_INFO, "Tied " << node->getPath() ); + SG_LOG( SG_ALL, SG_DEBUG, "Tied " << node->getPath() ); push_back( node ); } else { #if PROPS_STANDALONE @@ -125,7 +125,7 @@ public: void Untie() { while( size() > 0 ) { - SG_LOG( SG_ALL, SG_INFO, "untie of " << back()->getPath() ); + SG_LOG( SG_ALL, SG_DEBUG, "untie of " << back()->getPath() ); back()->untie(); pop_back(); } From be7065674586ffbb5940ab21a028bc8c461217e2 Mon Sep 17 00:00:00 2001 From: Mathias Froehlich Date: Sun, 30 Oct 2011 10:23:59 +0100 Subject: [PATCH 25/25] Add a HLADataElementVisitor implementation. --- simgear/hla/CMakeLists.txt | 1 + simgear/hla/HLAArrayDataElement.cxx | 14 ++ simgear/hla/HLAArrayDataElement.hxx | 3 + simgear/hla/HLABasicDataElement.cxx | 13 ++ simgear/hla/HLABasicDataElement.hxx | 7 + simgear/hla/HLADataElement.cxx | 14 ++ simgear/hla/HLADataElement.hxx | 8 +- simgear/hla/HLADataElementVisitor.hxx | 57 ++++++ simgear/hla/HLAEnumeratedDataElement.cxx | 14 ++ simgear/hla/HLAEnumeratedDataElement.hxx | 3 + simgear/hla/HLAFixedRecordDataElement.cxx | 14 ++ simgear/hla/HLAFixedRecordDataElement.hxx | 3 + simgear/hla/HLAPropertyDataElement.cxx | 216 ++++++++-------------- simgear/hla/HLAPropertyDataElement.hxx | 3 + simgear/hla/HLAVariantDataElement.cxx | 14 ++ simgear/hla/HLAVariantDataElement.hxx | 3 + simgear/hla/Makefile.am | 1 + 17 files changed, 245 insertions(+), 143 deletions(-) create mode 100644 simgear/hla/HLADataElementVisitor.hxx diff --git a/simgear/hla/CMakeLists.txt b/simgear/hla/CMakeLists.txt index a822fc24..f9c35c5e 100644 --- a/simgear/hla/CMakeLists.txt +++ b/simgear/hla/CMakeLists.txt @@ -7,6 +7,7 @@ set(HLA_HEADERS HLABasicDataElement.hxx HLABasicDataType.hxx HLADataElement.hxx + HLADataElementVisitor.hxx HLADataType.hxx HLADataTypeVisitor.hxx HLAEnumeratedDataElement.hxx diff --git a/simgear/hla/HLAArrayDataElement.cxx b/simgear/hla/HLAArrayDataElement.cxx index e2a7fc73..01e40243 100644 --- a/simgear/hla/HLAArrayDataElement.cxx +++ b/simgear/hla/HLAArrayDataElement.cxx @@ -19,6 +19,8 @@ #include +#include "HLADataElementVisitor.hxx" + namespace simgear { HLAAbstractArrayDataElement::HLAAbstractArrayDataElement(const HLAArrayDataType* dataType) : @@ -30,6 +32,18 @@ HLAAbstractArrayDataElement::~HLAAbstractArrayDataElement() { } +void +HLAAbstractArrayDataElement::accept(HLADataElementVisitor& visitor) +{ + visitor.apply(*this); +} + +void +HLAAbstractArrayDataElement::accept(HLAConstDataElementVisitor& visitor) const +{ + visitor.apply(*this); +} + bool HLAAbstractArrayDataElement::decode(HLADecodeStream& stream) { diff --git a/simgear/hla/HLAArrayDataElement.hxx b/simgear/hla/HLAArrayDataElement.hxx index b7c9c1e3..c236c4e4 100644 --- a/simgear/hla/HLAArrayDataElement.hxx +++ b/simgear/hla/HLAArrayDataElement.hxx @@ -33,6 +33,9 @@ public: HLAAbstractArrayDataElement(const HLAArrayDataType* dataType); virtual ~HLAAbstractArrayDataElement(); + virtual void accept(HLADataElementVisitor& visitor); + virtual void accept(HLAConstDataElementVisitor& visitor) const; + virtual bool decode(HLADecodeStream& stream); virtual bool encode(HLAEncodeStream& stream) const; diff --git a/simgear/hla/HLABasicDataElement.cxx b/simgear/hla/HLABasicDataElement.cxx index 69401104..f68cad36 100644 --- a/simgear/hla/HLABasicDataElement.cxx +++ b/simgear/hla/HLABasicDataElement.cxx @@ -17,6 +17,7 @@ #include "HLABasicDataElement.hxx" +#include "HLADataElementVisitor.hxx" #include "HLADataTypeVisitor.hxx" namespace simgear { @@ -30,6 +31,18 @@ HLABasicDataElement::~HLABasicDataElement() { } +void +HLABasicDataElement::accept(HLADataElementVisitor& visitor) +{ + visitor.apply(*this); +} + +void +HLABasicDataElement::accept(HLAConstDataElementVisitor& visitor) const +{ + visitor.apply(*this); +} + const HLABasicDataType* HLABasicDataElement::getDataType() const { diff --git a/simgear/hla/HLABasicDataElement.hxx b/simgear/hla/HLABasicDataElement.hxx index e38499df..70c275be 100644 --- a/simgear/hla/HLABasicDataElement.hxx +++ b/simgear/hla/HLABasicDataElement.hxx @@ -28,6 +28,12 @@ public: HLABasicDataElement(const HLABasicDataType* dataType); virtual ~HLABasicDataElement(); + virtual void accept(HLADataElementVisitor& visitor); + virtual void accept(HLAConstDataElementVisitor& visitor) const; + + virtual bool encode(HLAEncodeStream& stream) const = 0; + virtual bool decode(HLADecodeStream& stream) = 0; + virtual const HLABasicDataType* getDataType() const; virtual bool setDataType(const HLADataType* dataType); void setDataType(const HLABasicDataType* dataType); @@ -41,6 +47,7 @@ class HLAAbstract##type##DataElement : public HLABasicDataElement { \ public: \ HLAAbstract##type##DataElement(const HLABasicDataType* dataType = 0); \ virtual ~HLAAbstract##type##DataElement(); \ + \ virtual bool encode(HLAEncodeStream& stream) const; \ virtual bool decode(HLADecodeStream& stream); \ \ diff --git a/simgear/hla/HLADataElement.cxx b/simgear/hla/HLADataElement.cxx index ae981128..8245bddd 100644 --- a/simgear/hla/HLADataElement.cxx +++ b/simgear/hla/HLADataElement.cxx @@ -19,6 +19,8 @@ #include +#include "HLADataElementVisitor.hxx" + namespace simgear { HLADataElement::PathElement::Data::~Data() @@ -129,6 +131,18 @@ HLADataElement::~HLADataElement() { } +void +HLADataElement::accept(HLADataElementVisitor& visitor) +{ + visitor.apply(*this); +} + +void +HLADataElement::accept(HLAConstDataElementVisitor& visitor) const +{ + visitor.apply(*this); +} + std::string HLADataElement::toString(const Path& path) { diff --git a/simgear/hla/HLADataElement.hxx b/simgear/hla/HLADataElement.hxx index 284422b8..e3d52933 100644 --- a/simgear/hla/HLADataElement.hxx +++ b/simgear/hla/HLADataElement.hxx @@ -1,4 +1,4 @@ -// Copyright (C) 2009 - 2010 Mathias Froehlich - Mathias.Froehlich@web.de +// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Library General Public @@ -30,10 +30,16 @@ class SGTimeStamp; namespace simgear { +class HLADataElementVisitor; +class HLAConstDataElementVisitor; + class HLADataElement : public SGReferenced { public: virtual ~HLADataElement(); + virtual void accept(HLADataElementVisitor& visitor) = 0; + virtual void accept(HLAConstDataElementVisitor& visitor) const = 0; + virtual bool encode(HLAEncodeStream& stream) const = 0; virtual bool decode(HLADecodeStream& stream) = 0; diff --git a/simgear/hla/HLADataElementVisitor.hxx b/simgear/hla/HLADataElementVisitor.hxx new file mode 100644 index 00000000..938f7302 --- /dev/null +++ b/simgear/hla/HLADataElementVisitor.hxx @@ -0,0 +1,57 @@ +// Copyright (C) 2009 - 2011 Mathias Froehlich - Mathias.Froehlich@web.de +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// + +#ifndef HLADataElementVisitor_hxx +#define HLADataElementVisitor_hxx + +namespace simgear { + +class HLABasicDataElement; +class HLAAbstractEnumeratedDataElement; +class HLAAbstractFixedRecordDataElement; +class HLAAbstractArrayDataElement; +class HLAAbstractVariantDataElement; + +class HLADataElementVisitor { +public: + virtual ~HLADataElementVisitor() {} + + virtual void apply(HLADataElement&); + + virtual void apply(HLABasicDataElement&); + virtual void apply(HLAAbstractEnumeratedDataElement&); + virtual void apply(HLAAbstractArrayDataElement&); + virtual void apply(HLAAbstractFixedRecordDataElement&); + virtual void apply(HLAAbstractVariantDataElement&); +}; + +class HLAConstDataElementVisitor { +public: + virtual ~HLAConstDataElementVisitor() {} + + virtual void apply(const HLADataElement&); + + virtual void apply(const HLABasicDataElement&); + virtual void apply(const HLAAbstractEnumeratedDataElement&); + virtual void apply(const HLAAbstractArrayDataElement&); + virtual void apply(const HLAAbstractFixedRecordDataElement&); + virtual void apply(const HLAAbstractVariantDataElement&); +}; + +} + +#endif diff --git a/simgear/hla/HLAEnumeratedDataElement.cxx b/simgear/hla/HLAEnumeratedDataElement.cxx index a09e0dec..d5af6d41 100644 --- a/simgear/hla/HLAEnumeratedDataElement.cxx +++ b/simgear/hla/HLAEnumeratedDataElement.cxx @@ -19,6 +19,8 @@ #include +#include "HLADataElementVisitor.hxx" + namespace simgear { HLAAbstractEnumeratedDataElement::HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType) : @@ -30,6 +32,18 @@ HLAAbstractEnumeratedDataElement::~HLAAbstractEnumeratedDataElement() { } +void +HLAAbstractEnumeratedDataElement::accept(HLADataElementVisitor& visitor) +{ + visitor.apply(*this); +} + +void +HLAAbstractEnumeratedDataElement::accept(HLAConstDataElementVisitor& visitor) const +{ + visitor.apply(*this); +} + bool HLAAbstractEnumeratedDataElement::decode(HLADecodeStream& stream) { diff --git a/simgear/hla/HLAEnumeratedDataElement.hxx b/simgear/hla/HLAEnumeratedDataElement.hxx index f7dfbd38..10d8f105 100644 --- a/simgear/hla/HLAEnumeratedDataElement.hxx +++ b/simgear/hla/HLAEnumeratedDataElement.hxx @@ -28,6 +28,9 @@ public: HLAAbstractEnumeratedDataElement(const HLAEnumeratedDataType* dataType); virtual ~HLAAbstractEnumeratedDataElement(); + virtual void accept(HLADataElementVisitor& visitor); + virtual void accept(HLAConstDataElementVisitor& visitor) const; + virtual bool decode(HLADecodeStream& stream); virtual bool encode(HLAEncodeStream& stream) const; diff --git a/simgear/hla/HLAFixedRecordDataElement.cxx b/simgear/hla/HLAFixedRecordDataElement.cxx index d0980b95..c4c0c8b2 100644 --- a/simgear/hla/HLAFixedRecordDataElement.cxx +++ b/simgear/hla/HLAFixedRecordDataElement.cxx @@ -20,6 +20,8 @@ #include #include #include + +#include "HLADataElementVisitor.hxx" #include "HLADataTypeVisitor.hxx" namespace simgear { @@ -33,6 +35,18 @@ HLAAbstractFixedRecordDataElement::~HLAAbstractFixedRecordDataElement() { } +void +HLAAbstractFixedRecordDataElement::accept(HLADataElementVisitor& visitor) +{ + visitor.apply(*this); +} + +void +HLAAbstractFixedRecordDataElement::accept(HLAConstDataElementVisitor& visitor) const +{ + visitor.apply(*this); +} + bool HLAAbstractFixedRecordDataElement::decode(HLADecodeStream& stream) { diff --git a/simgear/hla/HLAFixedRecordDataElement.hxx b/simgear/hla/HLAFixedRecordDataElement.hxx index d99719d0..ca8ed997 100644 --- a/simgear/hla/HLAFixedRecordDataElement.hxx +++ b/simgear/hla/HLAFixedRecordDataElement.hxx @@ -30,6 +30,9 @@ public: HLAAbstractFixedRecordDataElement(const HLAFixedRecordDataType* dataType); virtual ~HLAAbstractFixedRecordDataElement(); + virtual void accept(HLADataElementVisitor& visitor); + virtual void accept(HLAConstDataElementVisitor& visitor) const; + virtual bool decode(HLADecodeStream& stream); virtual bool encode(HLAEncodeStream& stream) const; diff --git a/simgear/hla/HLAPropertyDataElement.cxx b/simgear/hla/HLAPropertyDataElement.cxx index e8a931ee..af19ff4d 100644 --- a/simgear/hla/HLAPropertyDataElement.cxx +++ b/simgear/hla/HLAPropertyDataElement.cxx @@ -18,6 +18,8 @@ #include "HLAPropertyDataElement.hxx" #include "HLAArrayDataElement.hxx" +#include "HLABasicDataElement.hxx" +#include "HLADataElementVisitor.hxx" #include "HLADataTypeVisitor.hxx" #include "HLAFixedRecordDataElement.hxx" #include "HLAVariantDataElement.hxx" @@ -152,7 +154,7 @@ protected: const SGPropertyNode& _propertyNode; }; -class HLAPropertyDataElement::ScalarDataElement : public HLADataElement { +class HLAPropertyDataElement::ScalarDataElement : public HLABasicDataElement { public: ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode); virtual ~ScalarDataElement(); @@ -160,16 +162,12 @@ public: virtual bool encode(HLAEncodeStream& stream) const; virtual bool decode(HLADecodeStream& stream); - virtual const HLADataType* getDataType() const; - virtual bool setDataType(const HLADataType* dataType); - private: - SGSharedPtr _dataType; SGSharedPtr _propertyNode; }; HLAPropertyDataElement::ScalarDataElement::ScalarDataElement(const HLABasicDataType* dataType, SGPropertyNode* propertyNode) : - _dataType(dataType), + HLABasicDataElement(dataType), _propertyNode(propertyNode) { } @@ -194,162 +192,64 @@ HLAPropertyDataElement::ScalarDataElement::decode(HLADecodeStream& stream) return true; } -const HLADataType* -HLAPropertyDataElement::ScalarDataElement::getDataType() const -{ - return _dataType.get(); -} - -bool -HLAPropertyDataElement::ScalarDataElement::setDataType(const HLADataType* dataType) -{ - if (!dataType) - return false; - const HLABasicDataType* basicDataType = dataType->toBasicDataType(); - if (!basicDataType) - return false; - _dataType = basicDataType; - return true; -} - - -class HLAPropertyDataElement::StringDecodeVisitor : public HLADataTypeDecodeVisitor { -public: - StringDecodeVisitor(HLADecodeStream& stream, SGPropertyNode& propertyNode) : - HLADataTypeDecodeVisitor(stream), - _propertyNode(propertyNode) - { } - - virtual void apply(const HLAFixedArrayDataType& dataType) - { - unsigned numElements = dataType.getNumElements(); - std::string value; - value.reserve(numElements); - for (unsigned i = 0; i < numElements; ++i) { - HLATemplateDecodeVisitor visitor(_stream); - dataType.getElementDataType()->accept(visitor); - value.push_back(visitor.getValue()); - } - _propertyNode.setStringValue(value); - } - virtual void apply(const HLAVariableArrayDataType& dataType) - { - HLATemplateDecodeVisitor numElementsVisitor(_stream); - dataType.getSizeDataType()->accept(numElementsVisitor); - std::string::size_type numElements = numElementsVisitor.getValue(); - std::string value; - value.reserve(numElements); - for (std::string::size_type i = 0; i < numElements; ++i) { - HLATemplateDecodeVisitor visitor(_stream); - dataType.getElementDataType()->accept(visitor); - value.push_back(visitor.getValue()); - } - _propertyNode.setStringValue(value); - } - -protected: - SGPropertyNode& _propertyNode; -}; - -class HLAPropertyDataElement::StringEncodeVisitor : public HLADataTypeEncodeVisitor { -public: - StringEncodeVisitor(HLAEncodeStream& stream, const SGPropertyNode& propertyNode) : - HLADataTypeEncodeVisitor(stream), - _propertyNode(propertyNode) - { } - - virtual void apply(const HLAFixedArrayDataType& dataType) - { - unsigned numElements = dataType.getNumElements(); - std::string value = _propertyNode.getStringValue(); - for (unsigned i = 0; i < numElements; ++i) { - if (i < value.size()) { - HLATemplateEncodeVisitor visitor(_stream, value[i]); - dataType.getElementDataType()->accept(visitor); - } else { - HLADataTypeEncodeVisitor visitor(_stream); - dataType.getElementDataType()->accept(visitor); - } - } - } - - virtual void apply(const HLAVariableArrayDataType& dataType) - { - std::string value = _propertyNode.getStringValue(); - HLATemplateEncodeVisitor numElementsVisitor(_stream, value.size()); - dataType.getSizeDataType()->accept(numElementsVisitor); - for (unsigned i = 0; i < value.size(); ++i) { - HLATemplateEncodeVisitor visitor(_stream, value[i]); - dataType.getElementDataType()->accept(visitor); - } - } - -protected: - const SGPropertyNode& _propertyNode; -}; - -class HLAPropertyDataElement::StringDataElement : public HLADataElement { +class HLAPropertyDataElement::StringDataElement : public HLAStringDataElement { public: StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode); virtual ~StringDataElement(); - virtual bool encode(HLAEncodeStream& stream) const; - virtual bool decode(HLADecodeStream& stream); + virtual bool decodeElement(HLADecodeStream& stream, unsigned i); - virtual const HLADataType* getDataType() const; - virtual bool setDataType(const HLADataType* dataType); + class Listener : public SGPropertyChangeListener { + public: + Listener(StringDataElement* stringDataElement); + virtual ~Listener(); + virtual void valueChanged (SGPropertyNode * node); + private: + StringDataElement* _stringDataElement; + }; private: - SGSharedPtr _dataType; SGSharedPtr _propertyNode; + Listener* _listener; }; -HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) : - _dataType(dataType), - _propertyNode(propertyNode) +HLAPropertyDataElement::StringDataElement::Listener::Listener(StringDataElement* stringDataElement) : + _stringDataElement(stringDataElement) { } +HLAPropertyDataElement::StringDataElement::Listener::~Listener() +{ +} + +void +HLAPropertyDataElement::StringDataElement::Listener::valueChanged (SGPropertyNode * node) +{ + _stringDataElement->setValue(node->getStringValue()); +} + +HLAPropertyDataElement::StringDataElement::StringDataElement(const HLAArrayDataType* dataType, SGPropertyNode* propertyNode) : + HLAStringDataElement(dataType), + _propertyNode(propertyNode), + _listener(new Listener(this)) +{ + _propertyNode->addChangeListener(_listener, true); +} + HLAPropertyDataElement::StringDataElement::~StringDataElement() { + _propertyNode->removeChangeListener(_listener); + delete _listener; + _listener = 0; } bool -HLAPropertyDataElement::StringDataElement::encode(HLAEncodeStream& stream) const +HLAPropertyDataElement::StringDataElement::decodeElement(HLADecodeStream& stream, unsigned i) { - StringEncodeVisitor visitor(stream, *_propertyNode); - _dataType->accept(visitor); - return true; -} - -bool -HLAPropertyDataElement::StringDataElement::decode(HLADecodeStream& stream) -{ - StringDecodeVisitor visitor(stream, *_propertyNode); - _dataType->accept(visitor); - return true; -} - -const HLADataType* -HLAPropertyDataElement::StringDataElement::getDataType() const -{ - return _dataType.get(); -} - -bool -HLAPropertyDataElement::StringDataElement::setDataType(const HLADataType* dataType) -{ - if (!dataType) + if (!HLAStringDataElement::decodeElement(stream, i)) return false; - const HLAArrayDataType* arrayDataType = dataType->toArrayDataType(); - if (!arrayDataType) - return false; - const HLADataType* elementDataType = arrayDataType->getElementDataType(); - if (!elementDataType) - return false; - if (!elementDataType->toBasicDataType()) - return false; - _dataType = arrayDataType; + if (i + 1 == getValue().size()) + _propertyNode->setStringValue(getValue()); return true; } @@ -534,6 +434,38 @@ HLAPropertyDataElement::~HLAPropertyDataElement() { } +void +HLAPropertyDataElement::accept(HLADataElementVisitor& visitor) +{ + if (_dataElement.valid()) { + visitor.apply(*_dataElement); + } else { + // We cant do anything if the data type is not valid + if (_dataType.valid()) { + HLADataElementFactoryVisitor factoryVisitor; + _dataType->accept(factoryVisitor); + _dataElement = factoryVisitor.getDataElement(); + if (_dataElement.valid()) { + visitor.apply(*_dataElement); + } else { + HLADataElement::accept(visitor); + } + } else { + HLADataElement::accept(visitor); + } + } +} + +void +HLAPropertyDataElement::accept(HLAConstDataElementVisitor& visitor) const +{ + if (_dataElement.valid()) { + visitor.apply(*_dataElement); + } else { + HLADataElement::accept(visitor); + } +} + bool HLAPropertyDataElement::encode(HLAEncodeStream& stream) const { diff --git a/simgear/hla/HLAPropertyDataElement.hxx b/simgear/hla/HLAPropertyDataElement.hxx index 4354a1d9..da21b2ab 100644 --- a/simgear/hla/HLAPropertyDataElement.hxx +++ b/simgear/hla/HLAPropertyDataElement.hxx @@ -31,6 +31,9 @@ public: HLAPropertyDataElement(const HLADataType* dataType); virtual ~HLAPropertyDataElement(); + virtual void accept(HLADataElementVisitor& visitor); + virtual void accept(HLAConstDataElementVisitor& visitor) const; + virtual bool encode(HLAEncodeStream& stream) const; virtual bool decode(HLADecodeStream& stream); diff --git a/simgear/hla/HLAVariantDataElement.cxx b/simgear/hla/HLAVariantDataElement.cxx index 98c22f78..2eca369a 100644 --- a/simgear/hla/HLAVariantDataElement.cxx +++ b/simgear/hla/HLAVariantDataElement.cxx @@ -19,6 +19,8 @@ #include +#include "HLADataElementVisitor.hxx" + namespace simgear { HLAAbstractVariantDataElement::HLAAbstractVariantDataElement(const HLAVariantDataType* dataType) : @@ -30,6 +32,18 @@ HLAAbstractVariantDataElement::~HLAAbstractVariantDataElement() { } +void +HLAAbstractVariantDataElement::accept(HLADataElementVisitor& visitor) +{ + visitor.apply(*this); +} + +void +HLAAbstractVariantDataElement::accept(HLAConstDataElementVisitor& visitor) const +{ + visitor.apply(*this); +} + bool HLAAbstractVariantDataElement::decode(HLADecodeStream& stream) { diff --git a/simgear/hla/HLAVariantDataElement.hxx b/simgear/hla/HLAVariantDataElement.hxx index b3ced7ca..0b14ef45 100644 --- a/simgear/hla/HLAVariantDataElement.hxx +++ b/simgear/hla/HLAVariantDataElement.hxx @@ -30,6 +30,9 @@ public: HLAAbstractVariantDataElement(const HLAVariantDataType* dataType); virtual ~HLAAbstractVariantDataElement(); + virtual void accept(HLADataElementVisitor& visitor); + virtual void accept(HLAConstDataElementVisitor& visitor) const; + virtual bool decode(HLADecodeStream& stream); virtual bool encode(HLAEncodeStream& stream) const; diff --git a/simgear/hla/Makefile.am b/simgear/hla/Makefile.am index e214e6a0..3bb38603 100644 --- a/simgear/hla/Makefile.am +++ b/simgear/hla/Makefile.am @@ -11,6 +11,7 @@ libsghla_a_HEADERS = \ HLABasicDataElement.hxx \ HLABasicDataType.hxx \ HLADataElement.hxx \ + HLADataElementVisitor.hxx \ HLADataType.hxx \ HLADataTypeVisitor.hxx \ HLAEnumeratedDataElement.hxx \